From 1390a3cd4f7bc55a37433d1d868e65c01678eb31 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Fri, 10 Apr 2026 10:05:07 -0500 Subject: [PATCH] ci: cache Robolectric SDK jars to prevent flaky SocketException failures (#5045) --- .github/actions/gradle-setup/action.yml | 9 + AGENTS.md | 3 +- .../main/kotlin/org/meshtastic/app/ui/Main.kt | 4 +- .../app/ui/NavigationAssemblyTest.kt | 4 +- core/navigation/README.md | 6 +- .../core/navigation/DeepLinkRouter.kt | 124 +++++++------- .../core/navigation/NavigationConfig.kt | 99 ++--------- .../org/meshtastic/core/navigation/Routes.kt | 155 +++++++++--------- .../core/navigation/TopLevelDestination.kt | 10 +- .../core/navigation/MultiBackstackTest.kt | 10 +- .../core/ui/component/MeshtasticAppShell.kt | 4 +- .../ui/component/MeshtasticNavigationSuite.kt | 8 +- .../kotlin/org/meshtastic/desktop/Main.kt | 4 +- .../DesktopTopLevelDestinationParityTest.kt | 24 +-- .../navigation/ConnectionsNavigation.kt | 18 +- .../connections/ui/ConnectionsScreen.kt | 6 +- .../firmware/navigation/FirmwareNavigation.kt | 6 +- .../feature/map/navigation/MapNavigation.kt | 10 +- .../navigation/ContactsNavigation.kt | 20 +-- .../ui/contact/AdaptiveContactsScreen.kt | 14 +- .../node/component/AdministrationSection.kt | 4 +- .../meshtastic/feature/node/model/LogsType.kt | 22 +-- .../node/navigation/AdaptiveNodeListScreen.kt | 8 +- .../node/navigation/NodesNavigation.kt | 82 ++++----- .../feature/settings/SettingsScreen.kt | 8 +- .../navigation/AboutLibrariesLoader.kt | 4 +- .../settings/navigation/ConfigRoute.kt | 22 +-- .../settings/navigation/ModuleRoute.kt | 34 ++-- .../settings/navigation/SettingsNavigation.kt | 32 ++-- .../feature/settings/radio/RadioConfig.kt | 16 +- .../radio/channel/ChannelsNavigation.kt | 8 +- .../feature/settings/DesktopSettingsScreen.kt | 8 +- .../navigation/AboutLibrariesLoader.kt | 4 +- .../navigation/WifiProvisionNavigation.kt | 10 +- 34 files changed, 374 insertions(+), 426 deletions(-) diff --git a/.github/actions/gradle-setup/action.yml b/.github/actions/gradle-setup/action.yml index 8caf40c78..89dda7411 100644 --- a/.github/actions/gradle-setup/action.yml +++ b/.github/actions/gradle-setup/action.yml @@ -27,6 +27,15 @@ runs: distribution: ${{ inputs.jdk_distribution }} token: ${{ github.token }} + # Robolectric downloads instrumented SDK jars from Maven Central at test time. + # Cache them to avoid flaky SocketException failures on CI runners. + # Update the key when bumping robolectric version in libs.versions.toml or sdk in robolectric.properties. + - name: Cache Robolectric SDK jars + uses: actions/cache@v4 + with: + path: ~/.m2/repository/org/robolectric + key: robolectric-4.16.1-sdk34 + - name: Setup Gradle uses: gradle/actions/setup-gradle@v6 with: diff --git a/AGENTS.md b/AGENTS.md index 40adbfd06..b5aa22fb7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,7 +41,7 @@ Meshtastic-Android is a Kotlin Multiplatform (KMP) application for off-grid, dec | `core:data` | Core manager implementations and data orchestration. | | `core:network` | KMP networking layer using Ktor, MQTT abstractions, and shared transport (`StreamFrameCodec`, `TcpTransport`, `SerialTransport`, `BleRadioInterface`). | | `core:di` | Common DI qualifiers and dispatchers. | -| `core:navigation` | Shared navigation keys/routes for Navigation 3, `DeepLinkRouter` for typed backstack synthesis, and `MeshtasticNavSavedStateConfig` for backstack persistence. | +| `core:navigation` | Shared navigation keys/routes for Navigation 3 using `@Serializable sealed interface` hierarchies per feature domain (e.g., `SettingsRoute`, `NodesRoute`). `DeepLinkRouter` for typed backstack synthesis, and `MeshtasticNavSavedStateConfig` with `subclassesOfSealed()` for automatic polymorphic backstack persistence — new routes are registered at compile time. | | `core:ui` | Shared Compose UI components (`MeshtasticAppShell`, `MeshtasticNavDisplay`, `MeshtasticNavigationSuite`, `AlertHost`, `SharedDialogs`, `PlaceholderScreen`, `MainAppBar`, dialogs, preferences) and platform abstractions. | | `core:service` | KMP service layer; Android bindings stay in `androidMain`. | | `core:api` | Public AIDL/API integration module for external clients. | @@ -189,6 +189,7 @@ Always run commands in the following order to ensure reliability. Do not attempt - **`maxParallelForks` CI logic:** ProjectExtensions.kt line ~79 checks `project.findProperty("ci") == "true"` and uses full available processors in CI (4 forks on std runners) vs. half locally. All CI invocations pass `-Pci=true` to enable this. - **Detekt report formats:** Detekt.kt line ~44 checks `project.findProperty("ci") == "true"` and disables html, txt, md reports in CI; only xml + sarif are required for GitHub reporting. - **KMP Smoke Compile:** Use `./gradlew kmpSmokeCompile` instead of listing individual module compile tasks. The `kmpSmokeCompile` lifecycle task (registered in `RootConventionPlugin`) auto-discovers all KMP modules and depends on their `compileKotlinJvm` + `compileKotlinIosSimulatorArm64` tasks. +- **Robolectric SDK caching:** The `gradle-setup` composite action caches `~/.m2/repository/org/robolectric` to prevent flaky `SocketException` failures when Robolectric downloads instrumented SDK jars. The cache key is `robolectric-{version}-sdk{level}` — update it when bumping the Robolectric version in `libs.versions.toml` or the SDK level in `robolectric.properties` / `@Config(sdk = ...)`. - **`mavenLocal()` gated:** The `mavenLocal()` repository is disabled by default to prevent CI cache poisoning. For local JitPack testing, pass `-PuseMavenLocal` to Gradle. - **Terminal Pagers:** When running shell commands like `git diff` or `git log`, ALWAYS use `--no-pager` (e.g., `git --no-pager diff`) to prevent the agent from getting stuck in an interactive prompt. - **Text Search:** Prefer using `rg` (ripgrep) over `grep` or `find` for fast text searching across the codebase. diff --git a/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt b/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt index 19c6c9ddf..1e5b68ab0 100644 --- a/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt +++ b/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt @@ -32,7 +32,7 @@ import co.touchlab.kermit.Logger import org.koin.compose.viewmodel.koinViewModel import org.meshtastic.app.BuildConfig import org.meshtastic.core.model.ConnectionState -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.navigation.rememberMultiBackstack import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.app_too_old @@ -53,7 +53,7 @@ import org.meshtastic.feature.wifiprovision.navigation.wifiProvisionGraph @Composable fun MainScreen() { val viewModel: UIViewModel = koinViewModel() - val multiBackstack = rememberMultiBackstack(NodesRoutes.NodesGraph) + val multiBackstack = rememberMultiBackstack(NodesRoute.NodesGraph) val backStack = multiBackstack.activeBackStack AndroidAppVersionCheck(viewModel) diff --git a/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt b/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt index ac082ffa3..ef4dab3e6 100644 --- a/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt +++ b/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt @@ -24,7 +24,7 @@ import kotlinx.coroutines.flow.emptyFlow import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.feature.connections.navigation.connectionsGraph import org.meshtastic.feature.firmware.navigation.firmwareGraph import org.meshtastic.feature.map.navigation.mapGraph @@ -44,7 +44,7 @@ class NavigationAssemblyTest { @Test fun verifyNavigationGraphsAssembleWithoutCrashing() { composeTestRule.setContent { - val backStack = rememberNavBackStack(NodesRoutes.NodesGraph) + val backStack = rememberNavBackStack(NodesRoute.NodesGraph) entryProvider { contactsGraph(backStack, emptyFlow()) nodesGraph(backStack = backStack, scrollToTopEvents = emptyFlow()) diff --git a/core/navigation/README.md b/core/navigation/README.md index 9927ebf7d..61e8b00ea 100644 --- a/core/navigation/README.md +++ b/core/navigation/README.md @@ -12,7 +12,7 @@ Contains serializable `NavKey` route classes/objects used by shared feature grap Parses Meshtastic deep-link URIs and synthesizes a typed backstack (for example `/nodes/1234/device-metrics`). ### 3. `NavigationConfig.kt` -Defines `MeshtasticNavSavedStateConfig` so Navigation 3 backstacks can be persisted/restored safely. +Defines `MeshtasticNavSavedStateConfig` using sealed interface hierarchies so Navigation 3 backstacks can be persisted/restored safely — new routes are auto-registered at compile time. ## Features - **Type-Safety**: Uses serializable `NavKey` routes instead of ad-hoc string routes. @@ -25,10 +25,10 @@ Feature modules depend on this module to define their entry points and navigate ```kotlin import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.NodesRoute fun openNodeDetail(backStack: NavBackStack, destNum: Int) { - backStack.add(NodesRoutes.NodeDetail(destNum)) + backStack.add(NodesRoute.NodeDetail(destNum)) } ``` diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt index 12f5a911c..0fdb4d48c 100644 --- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt +++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt @@ -59,11 +59,11 @@ object DeepLinkRouter { "messages", "quickchat", -> routeContacts(uri, pathSegments) - "connections" -> listOf(ConnectionsRoutes.ConnectionsGraph) + "connections" -> listOf(ConnectionsRoute.ConnectionsGraph) "map" -> routeMap(uri, pathSegments) "nodes" -> routeNodes(uri, pathSegments) "settings" -> routeSettings(pathSegments) - "channels" -> listOf(ChannelsRoutes.ChannelsGraph) + "channels" -> listOf(ChannelsRoute.ChannelsGraph) "firmware" -> routeFirmware(pathSegments) "wifi-provision" -> routeWifiProvision(uri) else -> { @@ -78,31 +78,31 @@ object DeepLinkRouter { return when (firstSegment) { "share" -> { val message = uri.getQueryParameter("message") ?: "" - listOf(ContactsRoutes.ContactsGraph, ContactsRoutes.Share(message)) + listOf(ContactsRoute.ContactsGraph, ContactsRoute.Share(message)) } "quickchat" -> { - listOf(ContactsRoutes.ContactsGraph, ContactsRoutes.QuickChat) + listOf(ContactsRoute.ContactsGraph, ContactsRoute.QuickChat) } "messages" -> { val contactKey = if (segments.size > 1) segments[1] else uri.getQueryParameter("contactKey") ?: "" val message = uri.getQueryParameter("message") ?: "" if (contactKey.isNotBlank()) { listOf( - ContactsRoutes.ContactsGraph, - ContactsRoutes.Messages(contactKey = contactKey, message = message), + ContactsRoute.ContactsGraph, + ContactsRoute.Messages(contactKey = contactKey, message = message), ) } else { - listOf(ContactsRoutes.ContactsGraph) + listOf(ContactsRoute.ContactsGraph) } } - else -> listOf(ContactsRoutes.ContactsGraph) + else -> listOf(ContactsRoute.ContactsGraph) } } private fun routeMap(uri: CommonUri, segments: List): List { val waypointIdStr = if (segments.size > 1) segments[1] else uri.getQueryParameter("waypointId") val waypointId = waypointIdStr?.toIntOrNull() - return listOf(MapRoutes.Map(waypointId)) + return listOf(MapRoute.Map(waypointId)) } private fun routeNodes(uri: CommonUri, segments: List): List { @@ -110,17 +110,17 @@ object DeepLinkRouter { val destNum = destNumStr?.toIntOrNull() return if (destNum == null) { - listOf(NodesRoutes.NodesGraph) + listOf(NodesRoute.NodesGraph) } else if (segments.size > 2) { val subRouteStr = segments[2].lowercase() val detailRouteFn = nodeDetailSubRoutes[subRouteStr] if (detailRouteFn != null) { - listOf(NodesRoutes.NodesGraph, NodesRoutes.NodeDetailGraph(destNum), detailRouteFn(destNum)) + listOf(NodesRoute.NodesGraph, NodesRoute.NodeDetailGraph(destNum), detailRouteFn(destNum)) } else { - listOf(NodesRoutes.NodesGraph, NodesRoutes.NodeDetail(destNum)) + listOf(NodesRoute.NodesGraph, NodesRoute.NodeDetail(destNum)) } } else { - listOf(NodesRoutes.NodesGraph, NodesRoutes.NodeDetail(destNum)) + listOf(NodesRoute.NodesGraph, NodesRoute.NodeDetail(destNum)) } } @@ -142,79 +142,79 @@ object DeepLinkRouter { } if (subRouteStr == null) { - return listOf(SettingsRoutes.SettingsGraph(destNum)) + return listOf(SettingsRoute.SettingsGraph(destNum)) } val subRoute = settingsSubRoutes[subRouteStr] return if (subRoute != null) { - listOf(SettingsRoutes.SettingsGraph(destNum), subRoute) + listOf(SettingsRoute.SettingsGraph(destNum), subRoute) } else { - listOf(SettingsRoutes.SettingsGraph(destNum)) + listOf(SettingsRoute.SettingsGraph(destNum)) } } private fun routeWifiProvision(uri: CommonUri): List { val address = uri.getQueryParameter("address") - return listOf(WifiProvisionRoutes.WifiProvision(address)) + return listOf(WifiProvisionRoute.WifiProvision(address)) } private fun routeFirmware(segments: List): List { val update = if (segments.size > 1) segments[1].lowercase() == "update" else false return if (update) { - listOf(FirmwareRoutes.FirmwareGraph, FirmwareRoutes.FirmwareUpdate) + listOf(FirmwareRoute.FirmwareGraph, FirmwareRoute.FirmwareUpdate) } else { - listOf(FirmwareRoutes.FirmwareGraph) + listOf(FirmwareRoute.FirmwareGraph) } } private val settingsSubRoutes: Map = mapOf( - "device-config" to SettingsRoutes.DeviceConfiguration, - "module-config" to SettingsRoutes.ModuleConfiguration, - "admin" to SettingsRoutes.Administration, - "user" to SettingsRoutes.User, - "channel" to SettingsRoutes.ChannelConfig, - "device" to SettingsRoutes.Device, - "position" to SettingsRoutes.Position, - "power" to SettingsRoutes.Power, - "network" to SettingsRoutes.Network, - "display" to SettingsRoutes.Display, - "lora" to SettingsRoutes.LoRa, - "bluetooth" to SettingsRoutes.Bluetooth, - "security" to SettingsRoutes.Security, - "mqtt" to SettingsRoutes.MQTT, - "serial" to SettingsRoutes.Serial, - "ext-notification" to SettingsRoutes.ExtNotification, - "store-forward" to SettingsRoutes.StoreForward, - "range-test" to SettingsRoutes.RangeTest, - "telemetry" to SettingsRoutes.Telemetry, - "canned-message" to SettingsRoutes.CannedMessage, - "audio" to SettingsRoutes.Audio, - "remote-hardware" to SettingsRoutes.RemoteHardware, - "neighbor-info" to SettingsRoutes.NeighborInfo, - "ambient-lighting" to SettingsRoutes.AmbientLighting, - "detection-sensor" to SettingsRoutes.DetectionSensor, - "paxcounter" to SettingsRoutes.Paxcounter, - "status-message" to SettingsRoutes.StatusMessage, - "traffic-management" to SettingsRoutes.TrafficManagement, - "tak" to SettingsRoutes.TAK, - "clean-node-db" to SettingsRoutes.CleanNodeDb, - "debug-panel" to SettingsRoutes.DebugPanel, - "about" to SettingsRoutes.About, - "filter-settings" to SettingsRoutes.FilterSettings, + "device-config" to SettingsRoute.DeviceConfiguration, + "module-config" to SettingsRoute.ModuleConfiguration, + "admin" to SettingsRoute.Administration, + "user" to SettingsRoute.User, + "channel" to SettingsRoute.ChannelConfig, + "device" to SettingsRoute.Device, + "position" to SettingsRoute.Position, + "power" to SettingsRoute.Power, + "network" to SettingsRoute.Network, + "display" to SettingsRoute.Display, + "lora" to SettingsRoute.LoRa, + "bluetooth" to SettingsRoute.Bluetooth, + "security" to SettingsRoute.Security, + "mqtt" to SettingsRoute.MQTT, + "serial" to SettingsRoute.Serial, + "ext-notification" to SettingsRoute.ExtNotification, + "store-forward" to SettingsRoute.StoreForward, + "range-test" to SettingsRoute.RangeTest, + "telemetry" to SettingsRoute.Telemetry, + "canned-message" to SettingsRoute.CannedMessage, + "audio" to SettingsRoute.Audio, + "remote-hardware" to SettingsRoute.RemoteHardware, + "neighbor-info" to SettingsRoute.NeighborInfo, + "ambient-lighting" to SettingsRoute.AmbientLighting, + "detection-sensor" to SettingsRoute.DetectionSensor, + "paxcounter" to SettingsRoute.Paxcounter, + "status-message" to SettingsRoute.StatusMessage, + "traffic-management" to SettingsRoute.TrafficManagement, + "tak" to SettingsRoute.TAK, + "clean-node-db" to SettingsRoute.CleanNodeDb, + "debug-panel" to SettingsRoute.DebugPanel, + "about" to SettingsRoute.About, + "filter-settings" to SettingsRoute.FilterSettings, ) private val nodeDetailSubRoutes: Map Route> = mapOf( - "device-metrics" to { destNum -> NodeDetailRoutes.DeviceMetrics(destNum) }, - "map" to { destNum -> NodeDetailRoutes.NodeMap(destNum) }, - "position" to { destNum -> NodeDetailRoutes.PositionLog(destNum) }, - "environment" to { destNum -> NodeDetailRoutes.EnvironmentMetrics(destNum) }, - "signal" to { destNum -> NodeDetailRoutes.SignalMetrics(destNum) }, - "power" to { destNum -> NodeDetailRoutes.PowerMetrics(destNum) }, - "traceroute" to { destNum -> NodeDetailRoutes.TracerouteLog(destNum) }, - "host-metrics" to { destNum -> NodeDetailRoutes.HostMetricsLog(destNum) }, - "pax" to { destNum -> NodeDetailRoutes.PaxMetrics(destNum) }, - "neighbors" to { destNum -> NodeDetailRoutes.NeighborInfoLog(destNum) }, + "device-metrics" to { destNum -> NodeDetailRoute.DeviceMetrics(destNum) }, + "map" to { destNum -> NodeDetailRoute.NodeMap(destNum) }, + "position" to { destNum -> NodeDetailRoute.PositionLog(destNum) }, + "environment" to { destNum -> NodeDetailRoute.EnvironmentMetrics(destNum) }, + "signal" to { destNum -> NodeDetailRoute.SignalMetrics(destNum) }, + "power" to { destNum -> NodeDetailRoute.PowerMetrics(destNum) }, + "traceroute" to { destNum -> NodeDetailRoute.TracerouteLog(destNum) }, + "host-metrics" to { destNum -> NodeDetailRoute.HostMetricsLog(destNum) }, + "pax" to { destNum -> NodeDetailRoute.PaxMetrics(destNum) }, + "neighbors" to { destNum -> NodeDetailRoute.NeighborInfoLog(destNum) }, ) } diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt index fe5c6225a..f52273f30 100644 --- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt +++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt @@ -18,99 +18,28 @@ package org.meshtastic.core.navigation import androidx.navigation3.runtime.NavKey import androidx.savedstate.serialization.SavedStateConfiguration +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic +import kotlinx.serialization.modules.subclassesOfSealed /** - * Shared polymorphic serialization configuration for Navigation 3 saved-state support. Registers all route types used - * across Android and Desktop navigation graphs. + * Shared polymorphic serialization configuration for Navigation 3 saved-state support. Uses sealed interface + * hierarchies so that new routes are automatically registered at compile time — no manual `subclass()` calls needed. */ +@OptIn(ExperimentalSerializationApi::class) val MeshtasticNavSavedStateConfig = SavedStateConfiguration { serializersModule = SerializersModule { polymorphic(NavKey::class) { - // Nodes - subclass(NodesRoutes.NodesGraph::class, NodesRoutes.NodesGraph.serializer()) - subclass(NodesRoutes.Nodes::class, NodesRoutes.Nodes.serializer()) - subclass(NodesRoutes.NodeDetailGraph::class, NodesRoutes.NodeDetailGraph.serializer()) - subclass(NodesRoutes.NodeDetail::class, NodesRoutes.NodeDetail.serializer()) - - // Node detail sub-screens - subclass(NodeDetailRoutes.DeviceMetrics::class, NodeDetailRoutes.DeviceMetrics.serializer()) - subclass(NodeDetailRoutes.NodeMap::class, NodeDetailRoutes.NodeMap.serializer()) - subclass(NodeDetailRoutes.PositionLog::class, NodeDetailRoutes.PositionLog.serializer()) - subclass(NodeDetailRoutes.EnvironmentMetrics::class, NodeDetailRoutes.EnvironmentMetrics.serializer()) - subclass(NodeDetailRoutes.SignalMetrics::class, NodeDetailRoutes.SignalMetrics.serializer()) - subclass(NodeDetailRoutes.PowerMetrics::class, NodeDetailRoutes.PowerMetrics.serializer()) - subclass(NodeDetailRoutes.TracerouteLog::class, NodeDetailRoutes.TracerouteLog.serializer()) - subclass(NodeDetailRoutes.TracerouteMap::class, NodeDetailRoutes.TracerouteMap.serializer()) - subclass(NodeDetailRoutes.HostMetricsLog::class, NodeDetailRoutes.HostMetricsLog.serializer()) - subclass(NodeDetailRoutes.PaxMetrics::class, NodeDetailRoutes.PaxMetrics.serializer()) - subclass(NodeDetailRoutes.NeighborInfoLog::class, NodeDetailRoutes.NeighborInfoLog.serializer()) - - // Conversations - subclass(ContactsRoutes.ContactsGraph::class, ContactsRoutes.ContactsGraph.serializer()) - subclass(ContactsRoutes.Contacts::class, ContactsRoutes.Contacts.serializer()) - subclass(ContactsRoutes.Messages::class, ContactsRoutes.Messages.serializer()) - subclass(ContactsRoutes.Share::class, ContactsRoutes.Share.serializer()) - subclass(ContactsRoutes.QuickChat::class, ContactsRoutes.QuickChat.serializer()) - - // Map - subclass(MapRoutes.Map::class, MapRoutes.Map.serializer()) - - // Firmware - subclass(FirmwareRoutes.FirmwareGraph::class, FirmwareRoutes.FirmwareGraph.serializer()) - subclass(FirmwareRoutes.FirmwareUpdate::class, FirmwareRoutes.FirmwareUpdate.serializer()) - - // Settings - subclass(SettingsRoutes.SettingsGraph::class, SettingsRoutes.SettingsGraph.serializer()) - subclass(SettingsRoutes.Settings::class, SettingsRoutes.Settings.serializer()) - subclass(SettingsRoutes.DeviceConfiguration::class, SettingsRoutes.DeviceConfiguration.serializer()) - subclass(SettingsRoutes.ModuleConfiguration::class, SettingsRoutes.ModuleConfiguration.serializer()) - subclass(SettingsRoutes.Administration::class, SettingsRoutes.Administration.serializer()) - - // Settings - Config routes - subclass(SettingsRoutes.User::class, SettingsRoutes.User.serializer()) - subclass(SettingsRoutes.ChannelConfig::class, SettingsRoutes.ChannelConfig.serializer()) - subclass(SettingsRoutes.Device::class, SettingsRoutes.Device.serializer()) - subclass(SettingsRoutes.Position::class, SettingsRoutes.Position.serializer()) - subclass(SettingsRoutes.Power::class, SettingsRoutes.Power.serializer()) - subclass(SettingsRoutes.Network::class, SettingsRoutes.Network.serializer()) - subclass(SettingsRoutes.Display::class, SettingsRoutes.Display.serializer()) - subclass(SettingsRoutes.LoRa::class, SettingsRoutes.LoRa.serializer()) - subclass(SettingsRoutes.Bluetooth::class, SettingsRoutes.Bluetooth.serializer()) - subclass(SettingsRoutes.Security::class, SettingsRoutes.Security.serializer()) - - // Settings - Module routes - subclass(SettingsRoutes.MQTT::class, SettingsRoutes.MQTT.serializer()) - subclass(SettingsRoutes.Serial::class, SettingsRoutes.Serial.serializer()) - subclass(SettingsRoutes.ExtNotification::class, SettingsRoutes.ExtNotification.serializer()) - subclass(SettingsRoutes.StoreForward::class, SettingsRoutes.StoreForward.serializer()) - subclass(SettingsRoutes.RangeTest::class, SettingsRoutes.RangeTest.serializer()) - subclass(SettingsRoutes.Telemetry::class, SettingsRoutes.Telemetry.serializer()) - subclass(SettingsRoutes.CannedMessage::class, SettingsRoutes.CannedMessage.serializer()) - subclass(SettingsRoutes.Audio::class, SettingsRoutes.Audio.serializer()) - subclass(SettingsRoutes.RemoteHardware::class, SettingsRoutes.RemoteHardware.serializer()) - subclass(SettingsRoutes.NeighborInfo::class, SettingsRoutes.NeighborInfo.serializer()) - subclass(SettingsRoutes.AmbientLighting::class, SettingsRoutes.AmbientLighting.serializer()) - subclass(SettingsRoutes.DetectionSensor::class, SettingsRoutes.DetectionSensor.serializer()) - subclass(SettingsRoutes.Paxcounter::class, SettingsRoutes.Paxcounter.serializer()) - subclass(SettingsRoutes.StatusMessage::class, SettingsRoutes.StatusMessage.serializer()) - subclass(SettingsRoutes.TrafficManagement::class, SettingsRoutes.TrafficManagement.serializer()) - subclass(SettingsRoutes.TAK::class, SettingsRoutes.TAK.serializer()) - - // Settings - Advanced routes - subclass(SettingsRoutes.CleanNodeDb::class, SettingsRoutes.CleanNodeDb.serializer()) - subclass(SettingsRoutes.DebugPanel::class, SettingsRoutes.DebugPanel.serializer()) - subclass(SettingsRoutes.About::class, SettingsRoutes.About.serializer()) - subclass(SettingsRoutes.FilterSettings::class, SettingsRoutes.FilterSettings.serializer()) - - // Channels - subclass(ChannelsRoutes.ChannelsGraph::class, ChannelsRoutes.ChannelsGraph.serializer()) - subclass(ChannelsRoutes.Channels::class, ChannelsRoutes.Channels.serializer()) - - // Connections - subclass(ConnectionsRoutes.ConnectionsGraph::class, ConnectionsRoutes.ConnectionsGraph.serializer()) - subclass(ConnectionsRoutes.Connections::class, ConnectionsRoutes.Connections.serializer()) + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() + subclassesOfSealed() } } } diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt index b58b20f2b..b1ccfb4c0 100644 --- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt +++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt @@ -25,160 +25,169 @@ interface Route : NavKey interface Graph : Route -object ChannelsRoutes { - @Serializable data object ChannelsGraph : Graph +@Serializable +sealed interface ChannelsRoute : Route { + @Serializable data object ChannelsGraph : ChannelsRoute, Graph - @Serializable data object Channels : Route + @Serializable data object Channels : ChannelsRoute } -object ConnectionsRoutes { - @Serializable data object ConnectionsGraph : Graph +@Serializable +sealed interface ConnectionsRoute : Route { + @Serializable data object ConnectionsGraph : ConnectionsRoute, Graph - @Serializable data object Connections : Route + @Serializable data object Connections : ConnectionsRoute } -object ContactsRoutes { - @Serializable data object ContactsGraph : Graph +@Serializable +sealed interface ContactsRoute : Route { + @Serializable data object ContactsGraph : ContactsRoute, Graph - @Serializable data object Contacts : Route + @Serializable data object Contacts : ContactsRoute - @Serializable data class Messages(val contactKey: String, val message: String = "") : Route + @Serializable data class Messages(val contactKey: String, val message: String = "") : ContactsRoute - @Serializable data class Share(val message: String) : Route + @Serializable data class Share(val message: String) : ContactsRoute - @Serializable data object QuickChat : Route + @Serializable data object QuickChat : ContactsRoute } -object MapRoutes { - @Serializable data class Map(val waypointId: Int? = null) : Route +@Serializable +sealed interface MapRoute : Route { + @Serializable data class Map(val waypointId: Int? = null) : MapRoute } -object NodesRoutes { - @Serializable data object NodesGraph : Graph +@Serializable +sealed interface NodesRoute : Route { + @Serializable data object NodesGraph : NodesRoute, Graph - @Serializable data object Nodes : Route + @Serializable data object Nodes : NodesRoute - @Serializable data class NodeDetailGraph(val destNum: Int? = null) : Graph + @Serializable data class NodeDetailGraph(val destNum: Int? = null) : NodesRoute, Graph - @Serializable data class NodeDetail(val destNum: Int? = null) : Route + @Serializable data class NodeDetail(val destNum: Int? = null) : NodesRoute } -object NodeDetailRoutes { - @Serializable data class DeviceMetrics(val destNum: Int) : Route +@Serializable +sealed interface NodeDetailRoute : Route { + @Serializable data class DeviceMetrics(val destNum: Int) : NodeDetailRoute - @Serializable data class NodeMap(val destNum: Int) : Route + @Serializable data class NodeMap(val destNum: Int) : NodeDetailRoute - @Serializable data class PositionLog(val destNum: Int) : Route + @Serializable data class PositionLog(val destNum: Int) : NodeDetailRoute - @Serializable data class EnvironmentMetrics(val destNum: Int) : Route + @Serializable data class EnvironmentMetrics(val destNum: Int) : NodeDetailRoute - @Serializable data class SignalMetrics(val destNum: Int) : Route + @Serializable data class SignalMetrics(val destNum: Int) : NodeDetailRoute - @Serializable data class PowerMetrics(val destNum: Int) : Route + @Serializable data class PowerMetrics(val destNum: Int) : NodeDetailRoute - @Serializable data class TracerouteLog(val destNum: Int) : Route + @Serializable data class TracerouteLog(val destNum: Int) : NodeDetailRoute - @Serializable data class TracerouteMap(val destNum: Int, val requestId: Int, val logUuid: String? = null) : Route + @Serializable data class TracerouteMap(val destNum: Int, val requestId: Int, val logUuid: String? = null) : NodeDetailRoute - @Serializable data class HostMetricsLog(val destNum: Int) : Route + @Serializable data class HostMetricsLog(val destNum: Int) : NodeDetailRoute - @Serializable data class PaxMetrics(val destNum: Int) : Route + @Serializable data class PaxMetrics(val destNum: Int) : NodeDetailRoute - @Serializable data class NeighborInfoLog(val destNum: Int) : Route + @Serializable data class NeighborInfoLog(val destNum: Int) : NodeDetailRoute } -object SettingsRoutes { - @Serializable data class SettingsGraph(val destNum: Int? = null) : Graph +@Serializable +sealed interface SettingsRoute : Route { + @Serializable data class SettingsGraph(val destNum: Int? = null) : SettingsRoute, Graph - @Serializable data class Settings(val destNum: Int? = null) : Route + @Serializable data class Settings(val destNum: Int? = null) : SettingsRoute - @Serializable data object DeviceConfiguration : Route + @Serializable data object DeviceConfiguration : SettingsRoute - @Serializable data object ModuleConfiguration : Route + @Serializable data object ModuleConfiguration : SettingsRoute - @Serializable data object Administration : Route + @Serializable data object Administration : SettingsRoute // region radio Config Routes - @Serializable data object User : Route + @Serializable data object User : SettingsRoute - @Serializable data object ChannelConfig : Route + @Serializable data object ChannelConfig : SettingsRoute - @Serializable data object Device : Route + @Serializable data object Device : SettingsRoute - @Serializable data object Position : Route + @Serializable data object Position : SettingsRoute - @Serializable data object Power : Route + @Serializable data object Power : SettingsRoute - @Serializable data object Network : Route + @Serializable data object Network : SettingsRoute - @Serializable data object Display : Route + @Serializable data object Display : SettingsRoute - @Serializable data object LoRa : Route + @Serializable data object LoRa : SettingsRoute - @Serializable data object Bluetooth : Route + @Serializable data object Bluetooth : SettingsRoute - @Serializable data object Security : Route + @Serializable data object Security : SettingsRoute // endregion // region module config routes - @Serializable data object MQTT : Route + @Serializable data object MQTT : SettingsRoute - @Serializable data object Serial : Route + @Serializable data object Serial : SettingsRoute - @Serializable data object ExtNotification : Route + @Serializable data object ExtNotification : SettingsRoute - @Serializable data object StoreForward : Route + @Serializable data object StoreForward : SettingsRoute - @Serializable data object RangeTest : Route + @Serializable data object RangeTest : SettingsRoute - @Serializable data object Telemetry : Route + @Serializable data object Telemetry : SettingsRoute - @Serializable data object CannedMessage : Route + @Serializable data object CannedMessage : SettingsRoute - @Serializable data object Audio : Route + @Serializable data object Audio : SettingsRoute - @Serializable data object RemoteHardware : Route + @Serializable data object RemoteHardware : SettingsRoute - @Serializable data object NeighborInfo : Route + @Serializable data object NeighborInfo : SettingsRoute - @Serializable data object AmbientLighting : Route + @Serializable data object AmbientLighting : SettingsRoute - @Serializable data object DetectionSensor : Route + @Serializable data object DetectionSensor : SettingsRoute - @Serializable data object Paxcounter : Route + @Serializable data object Paxcounter : SettingsRoute - @Serializable data object StatusMessage : Route + @Serializable data object StatusMessage : SettingsRoute - @Serializable data object TrafficManagement : Route + @Serializable data object TrafficManagement : SettingsRoute - @Serializable data object TAK : Route + @Serializable data object TAK : SettingsRoute // endregion // region advanced config routes - @Serializable data object CleanNodeDb : Route + @Serializable data object CleanNodeDb : SettingsRoute - @Serializable data object DebugPanel : Route + @Serializable data object DebugPanel : SettingsRoute - @Serializable data object About : Route + @Serializable data object About : SettingsRoute - @Serializable data object FilterSettings : Route + @Serializable data object FilterSettings : SettingsRoute // endregion } -object FirmwareRoutes { - @Serializable data object FirmwareGraph : Graph +@Serializable +sealed interface FirmwareRoute : Route { + @Serializable data object FirmwareGraph : FirmwareRoute, Graph - @Serializable data object FirmwareUpdate : Route + @Serializable data object FirmwareUpdate : FirmwareRoute } -object WifiProvisionRoutes { - @Serializable data object WifiProvisionGraph : Graph +@Serializable +sealed interface WifiProvisionRoute : Route { + @Serializable data object WifiProvisionGraph : WifiProvisionRoute, Graph - @Serializable data class WifiProvision(val address: String? = null) : Route + @Serializable data class WifiProvision(val address: String? = null) : WifiProvisionRoute } diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt index b25a61081..5f9603dd3 100644 --- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt +++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt @@ -32,11 +32,11 @@ import org.meshtastic.core.resources.nodes * and Desktop navigation shells. */ enum class TopLevelDestination(val label: StringResource, val route: Route) { - Conversations(Res.string.conversations, ContactsRoutes.ContactsGraph), - Nodes(Res.string.nodes, NodesRoutes.NodesGraph), - Map(Res.string.map, MapRoutes.Map()), - Settings(Res.string.bottom_nav_settings, SettingsRoutes.SettingsGraph()), - Connections(Res.string.connections, ConnectionsRoutes.ConnectionsGraph), + Conversations(Res.string.conversations, ContactsRoute.ContactsGraph), + Nodes(Res.string.nodes, NodesRoute.NodesGraph), + Map(Res.string.map, MapRoute.Map()), + Settings(Res.string.bottom_nav_settings, SettingsRoute.SettingsGraph()), + Connections(Res.string.connections, ConnectionsRoute.ConnectionsGraph), ; companion object { diff --git a/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt b/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt index 60ba3f6eb..c4d3ac044 100644 --- a/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt +++ b/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt @@ -29,7 +29,7 @@ class MultiBackstackTest { val multiBackstack = MultiBackstack(startTab) val nodesStack = - NavBackStack().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoutes.Nodes)) } + NavBackStack().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoute.Nodes)) } val mapStack = NavBackStack().apply { addAll(listOf(TopLevelDestination.Map.route)) } multiBackstack.backStacks = @@ -51,7 +51,7 @@ class MultiBackstackTest { val multiBackstack = MultiBackstack(startTab) val nodesStack = - NavBackStack().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoutes.Nodes)) } + NavBackStack().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoute.Nodes)) } multiBackstack.backStacks = mapOf(TopLevelDestination.Nodes.route to nodesStack) assertEquals(2, multiBackstack.activeBackStack.size) @@ -68,7 +68,7 @@ class MultiBackstackTest { val multiBackstack = MultiBackstack(startTab) val nodesStack = - NavBackStack().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoutes.Nodes)) } + NavBackStack().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoute.Nodes)) } multiBackstack.backStacks = mapOf(TopLevelDestination.Nodes.route to nodesStack) multiBackstack.goBack() @@ -104,11 +104,11 @@ class MultiBackstackTest { val settingsStack = NavBackStack().apply { addAll(listOf(TopLevelDestination.Settings.route)) } multiBackstack.backStacks = mapOf(TopLevelDestination.Settings.route to settingsStack) - val deepLinkPath = listOf(TopLevelDestination.Settings.route, SettingsRoutes.About) + val deepLinkPath = listOf(TopLevelDestination.Settings.route, SettingsRoute.About) multiBackstack.handleDeepLink(deepLinkPath) assertEquals(TopLevelDestination.Settings.route, multiBackstack.currentTabRoute) assertEquals(2, multiBackstack.activeBackStack.size) - assertEquals(SettingsRoutes.About, multiBackstack.activeBackStack.last()) + assertEquals(SettingsRoute.About, multiBackstack.activeBackStack.last()) } } diff --git a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt index 6ade7e3b2..8c96e88a4 100644 --- a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt +++ b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt @@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import org.meshtastic.core.navigation.MultiBackstack -import org.meshtastic.core.navigation.NodeDetailRoutes +import org.meshtastic.core.navigation.NodeDetailRoute import org.meshtastic.core.ui.viewmodel.UIViewModel /** @@ -44,7 +44,7 @@ fun MeshtasticAppShell( uiViewModel = uiViewModel, onNavigateToTracerouteMap = { destNum, requestId, logUuid -> multiBackstack.activeBackStack.add( - NodeDetailRoutes.TracerouteMap(destNum = destNum, requestId = requestId, logUuid = logUuid), + NodeDetailRoute.TracerouteMap(destNum = destNum, requestId = requestId, logUuid = logUuid), ) }, ) diff --git a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt index 1e0fae0c5..9f1f36637 100644 --- a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt +++ b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt @@ -50,9 +50,9 @@ import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.vectorResource import org.meshtastic.core.model.ConnectionState import org.meshtastic.core.model.DeviceType -import org.meshtastic.core.navigation.ContactsRoutes +import org.meshtastic.core.navigation.ContactsRoute import org.meshtastic.core.navigation.MultiBackstack -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.navigation.TopLevelDestination import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.connected @@ -141,7 +141,7 @@ private fun handleNavigation( val currentKey = multiBackstack.activeBackStack.lastOrNull() when (destination) { TopLevelDestination.Nodes -> { - val onNodesList = currentKey is NodesRoutes.NodesGraph || currentKey is NodesRoutes.Nodes + val onNodesList = currentKey is NodesRoute.NodesGraph || currentKey is NodesRoute.Nodes if (!onNodesList) { multiBackstack.navigateTopLevel(destination.route) } else { @@ -150,7 +150,7 @@ private fun handleNavigation( } TopLevelDestination.Conversations -> { val onConversationsList = - currentKey is ContactsRoutes.ContactsGraph || currentKey is ContactsRoutes.Contacts + currentKey is ContactsRoute.ContactsGraph || currentKey is ContactsRoute.Contacts if (!onConversationsList) { multiBackstack.navigateTopLevel(destination.route) } else { diff --git a/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt b/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt index bc0d3a144..0a450c007 100644 --- a/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt +++ b/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt @@ -62,7 +62,7 @@ import org.jetbrains.skia.Image import org.koin.core.context.startKoin import org.meshtastic.core.common.util.MeshtasticUri import org.meshtastic.core.database.desktopDataDir -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.navigation.TopLevelDestination import org.meshtastic.core.navigation.rememberMultiBackstack import org.meshtastic.core.repository.UiPrefs @@ -241,7 +241,7 @@ fun main(args: Array) = application(exitProcessOnExit = false) { true } event.key == Key.Slash -> { - backStack.add(SettingsRoutes.About) + backStack.add(SettingsRoute.About) true } else -> false diff --git a/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt b/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt index 01fec03b2..d14c2fe98 100644 --- a/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt +++ b/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt @@ -16,13 +16,13 @@ */ package org.meshtastic.desktop.ui -import org.meshtastic.core.navigation.ConnectionsRoutes -import org.meshtastic.core.navigation.ContactsRoutes -import org.meshtastic.core.navigation.FirmwareRoutes -import org.meshtastic.core.navigation.MapRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.ConnectionsRoute +import org.meshtastic.core.navigation.ContactsRoute +import org.meshtastic.core.navigation.FirmwareRoute +import org.meshtastic.core.navigation.MapRoute +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.navigation.TopLevelDestination import kotlin.reflect.KClass import kotlin.test.Test @@ -41,11 +41,11 @@ class DesktopTopLevelDestinationParityTest { val androidParityRoutes: Set> = setOf( - ContactsRoutes.ContactsGraph::class, - NodesRoutes.NodesGraph::class, - MapRoutes.Map::class, - SettingsRoutes.SettingsGraph::class, - ConnectionsRoutes.ConnectionsGraph::class, + ContactsRoute.ContactsGraph::class, + NodesRoute.NodesGraph::class, + MapRoute.Map::class, + SettingsRoute.SettingsGraph::class, + ConnectionsRoute.ConnectionsGraph::class, ) assertEquals( @@ -60,7 +60,7 @@ class DesktopTopLevelDestinationParityTest { val desktopRoutes: Set> = TopLevelDestination.entries.map { it.route::class }.toSet() assertFalse( - actual = desktopRoutes.contains(FirmwareRoutes.FirmwareGraph::class), + actual = desktopRoutes.contains(FirmwareRoute.FirmwareGraph::class), message = "Firmware must stay in-flow and not appear in the desktop top-level rail", ) } diff --git a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt index eabd920eb..152e880cb 100644 --- a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt +++ b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt @@ -20,30 +20,30 @@ import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import org.koin.compose.viewmodel.koinViewModel -import org.meshtastic.core.navigation.ConnectionsRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.ConnectionsRoute +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.feature.connections.ScannerViewModel import org.meshtastic.feature.connections.ui.ConnectionsScreen import org.meshtastic.feature.settings.radio.RadioConfigViewModel -/** Navigation graph for for the top level ConnectionsScreen - [ConnectionsRoutes.Connections]. */ +/** Navigation graph for for the top level ConnectionsScreen - [ConnectionsRoute.Connections]. */ fun EntryProviderScope.connectionsGraph(backStack: NavBackStack) { - entry { + entry { ConnectionsScreen( scanModel = koinViewModel(), radioConfigViewModel = koinViewModel(), - onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) }, - onNavigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) }, + onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) }, + onNavigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) }, onConfigNavigate = { route -> backStack.add(route) }, ) } - entry { + entry { ConnectionsScreen( scanModel = koinViewModel(), radioConfigViewModel = koinViewModel(), - onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) }, - onNavigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) }, + onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) }, + onNavigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) }, onConfigNavigate = { route -> backStack.add(route) }, ) } diff --git a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt index 05a172e1f..828b7be2f 100644 --- a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt +++ b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt @@ -51,7 +51,7 @@ import org.koin.compose.viewmodel.koinViewModel import org.meshtastic.core.model.ConnectionState import org.meshtastic.core.model.DeviceType import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.connected import org.meshtastic.core.resources.connected_device @@ -125,8 +125,8 @@ fun ConnectionsScreen( getNavRouteFrom(radioConfigState.route)?.let { route -> isWaiting = false radioConfigViewModel.clearPacketResponse() - if (route == SettingsRoutes.LoRa) { - onConfigNavigate(SettingsRoutes.LoRa) + if (route == SettingsRoute.LoRa) { + onConfigNavigate(SettingsRoute.LoRa) } } }, diff --git a/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt b/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt index 9ab1320b9..7980ad96a 100644 --- a/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt +++ b/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt @@ -21,14 +21,14 @@ import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import org.koin.compose.viewmodel.koinViewModel -import org.meshtastic.core.navigation.FirmwareRoutes +import org.meshtastic.core.navigation.FirmwareRoute import org.meshtastic.feature.firmware.FirmwareUpdateScreen import org.meshtastic.feature.firmware.FirmwareUpdateViewModel /** Registers the firmware update screen entries into the Navigation 3 entry provider. */ fun EntryProviderScope.firmwareGraph(backStack: NavBackStack) { - entry { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) } - entry { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) } + entry { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) } + entry { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) } } @Composable diff --git a/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt b/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt index fb921bdde..2c0b5e7b8 100644 --- a/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt +++ b/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt @@ -19,15 +19,15 @@ package org.meshtastic.feature.map.navigation import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey -import org.meshtastic.core.navigation.MapRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.MapRoute +import org.meshtastic.core.navigation.NodesRoute fun EntryProviderScope.mapGraph(backStack: NavBackStack) { - entry { args -> + entry { args -> val mapScreen = org.meshtastic.core.ui.util.LocalMapMainScreenProvider.current mapScreen( - { backStack.add(NodesRoutes.NodeDetail(it)) }, // onClickNodeChip - { backStack.add(NodesRoutes.NodeDetail(it)) }, // navigateToNodeDetails + { backStack.add(NodesRoute.NodeDetail(it)) }, // onClickNodeChip + { backStack.add(NodesRoute.NodeDetail(it)) }, // navigateToNodeDetails args.waypointId, ) } diff --git a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt index 1e83f8039..0f347f980 100644 --- a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt +++ b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt @@ -27,8 +27,8 @@ import androidx.navigation3.runtime.NavKey import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import org.koin.compose.viewmodel.koinViewModel -import org.meshtastic.core.navigation.ContactsRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.ContactsRoute +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.navigation.replaceLast import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.feature.messaging.QuickChatScreen @@ -43,15 +43,15 @@ fun EntryProviderScope.contactsGraph( backStack: NavBackStack, scrollToTopEvents: Flow = MutableSharedFlow(), ) { - entry(metadata = { ListDetailSceneStrategy.listPane() }) { + entry(metadata = { ListDetailSceneStrategy.listPane() }) { ContactsEntryContent(backStack = backStack, scrollToTopEvents = scrollToTopEvents) } - entry(metadata = { ListDetailSceneStrategy.listPane() }) { + entry(metadata = { ListDetailSceneStrategy.listPane() }) { ContactsEntryContent(backStack = backStack, scrollToTopEvents = scrollToTopEvents) } - entry(metadata = { ListDetailSceneStrategy.detailPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.detailPane() }) { args -> val contactKey = args.contactKey val messageViewModel: org.meshtastic.feature.messaging.MessageViewModel = koinViewModel(key = "messages-$contactKey") @@ -61,23 +61,23 @@ fun EntryProviderScope.contactsGraph( contactKey = contactKey, message = args.message, viewModel = messageViewModel, - navigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) }, - navigateToQuickChatOptions = { backStack.add(org.meshtastic.core.navigation.ContactsRoutes.QuickChat) }, + navigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) }, + navigateToQuickChatOptions = { backStack.add(org.meshtastic.core.navigation.ContactsRoute.QuickChat) }, onNavigateBack = { backStack.removeLastOrNull() }, ) } - entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> val message = args.message val viewModel = koinViewModel() ShareScreen( viewModel = viewModel, - onConfirm = { contactKey -> backStack.replaceLast(ContactsRoutes.Messages(contactKey, message)) }, + onConfirm = { contactKey -> backStack.replaceLast(ContactsRoute.Messages(contactKey, message)) }, onNavigateUp = { backStack.removeLastOrNull() }, ) } - entry(metadata = { ListDetailSceneStrategy.extraPane() }) { + entry(metadata = { ListDetailSceneStrategy.extraPane() }) { val viewModel = koinViewModel() QuickChatScreen(viewModel = viewModel, onNavigateUp = { backStack.removeLastOrNull() }) } diff --git a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt index df3d5a7ad..d8f7eeae0 100644 --- a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt +++ b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt @@ -21,9 +21,9 @@ import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import kotlinx.coroutines.flow.Flow import org.meshtastic.core.common.util.MeshtasticUri -import org.meshtastic.core.navigation.ChannelsRoutes -import org.meshtastic.core.navigation.ContactsRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.ChannelsRoute +import org.meshtastic.core.navigation.ContactsRoute +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.proto.ChannelSet import org.meshtastic.proto.SharedContact @@ -40,16 +40,16 @@ fun AdaptiveContactsScreen( onClearRequestChannelUrl: () -> Unit, ) { ContactsScreen( - onNavigateToShare = { backStack.add(ChannelsRoutes.ChannelsGraph) }, + onNavigateToShare = { backStack.add(ChannelsRoute.ChannelsGraph) }, sharedContactRequested = sharedContactRequested, requestChannelSet = requestChannelSet, onHandleDeepLink = onHandleDeepLink, onClearSharedContactRequested = onClearSharedContactRequested, onClearRequestChannelUrl = onClearRequestChannelUrl, viewModel = contactsViewModel, - onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) }, - onNavigateToMessages = { contactKey -> backStack.add(ContactsRoutes.Messages(contactKey)) }, - onNavigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) }, + onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) }, + onNavigateToMessages = { contactKey -> backStack.add(ContactsRoute.Messages(contactKey)) }, + onNavigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) }, scrollToTopEvents = scrollToTopEvents, activeContactKey = null, ) diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt index 5cd461210..23ef010e8 100644 --- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt +++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt @@ -27,7 +27,7 @@ import org.meshtastic.core.database.entity.asDeviceVersion import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.model.Node import org.meshtastic.core.model.service.ServiceAction -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.administration import org.meshtastic.core.resources.firmware @@ -77,7 +77,7 @@ fun AdministrationSection( leadingIcon = MeshtasticIcons.Settings, enabled = metricsState.isLocal || node.metadata != null, ) { - onAction(NodeDetailAction.Navigate(SettingsRoutes.Settings(node.num))) + onAction(NodeDetailAction.Navigate(SettingsRoute.Settings(node.num))) } } } diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt index b4db1b358..3bd4a4a5b 100644 --- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt +++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt @@ -18,7 +18,7 @@ package org.meshtastic.feature.node.model import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource -import org.meshtastic.core.navigation.NodeDetailRoutes +import org.meshtastic.core.navigation.NodeDetailRoute import org.meshtastic.core.navigation.Route import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.device_metrics_log @@ -43,14 +43,14 @@ import org.meshtastic.core.resources.signal_quality import org.meshtastic.core.resources.traceroute_log enum class LogsType(val titleRes: StringResource, val icon: DrawableResource, val routeFactory: (Int) -> Route) { - DEVICE(Res.string.device_metrics_log, Res.drawable.ic_charging_station, { NodeDetailRoutes.DeviceMetrics(it) }), - NODE_MAP(Res.string.node_map, Res.drawable.ic_map, { NodeDetailRoutes.NodeMap(it) }), - POSITIONS(Res.string.position_log, Res.drawable.ic_location_on, { NodeDetailRoutes.PositionLog(it) }), - ENVIRONMENT(Res.string.env_metrics_log, Res.drawable.ic_thermostat, { NodeDetailRoutes.EnvironmentMetrics(it) }), - SIGNAL(Res.string.signal_quality, Res.drawable.ic_signal_cellular_alt, { NodeDetailRoutes.SignalMetrics(it) }), - POWER(Res.string.power_metrics_log, Res.drawable.ic_power, { NodeDetailRoutes.PowerMetrics(it) }), - TRACEROUTE(Res.string.traceroute_log, Res.drawable.ic_route, { NodeDetailRoutes.TracerouteLog(it) }), - NEIGHBOR_INFO(Res.string.neighbor_info, Res.drawable.ic_groups, { NodeDetailRoutes.NeighborInfoLog(it) }), - HOST(Res.string.host_metrics_log, Res.drawable.ic_memory, { NodeDetailRoutes.HostMetricsLog(it) }), - PAX(Res.string.pax_metrics_log, Res.drawable.ic_people, { NodeDetailRoutes.PaxMetrics(it) }), + DEVICE(Res.string.device_metrics_log, Res.drawable.ic_charging_station, { NodeDetailRoute.DeviceMetrics(it) }), + NODE_MAP(Res.string.node_map, Res.drawable.ic_map, { NodeDetailRoute.NodeMap(it) }), + POSITIONS(Res.string.position_log, Res.drawable.ic_location_on, { NodeDetailRoute.PositionLog(it) }), + ENVIRONMENT(Res.string.env_metrics_log, Res.drawable.ic_thermostat, { NodeDetailRoute.EnvironmentMetrics(it) }), + SIGNAL(Res.string.signal_quality, Res.drawable.ic_signal_cellular_alt, { NodeDetailRoute.SignalMetrics(it) }), + POWER(Res.string.power_metrics_log, Res.drawable.ic_power, { NodeDetailRoute.PowerMetrics(it) }), + TRACEROUTE(Res.string.traceroute_log, Res.drawable.ic_route, { NodeDetailRoute.TracerouteLog(it) }), + NEIGHBOR_INFO(Res.string.neighbor_info, Res.drawable.ic_groups, { NodeDetailRoute.NeighborInfoLog(it) }), + HOST(Res.string.host_metrics_log, Res.drawable.ic_memory, { NodeDetailRoute.HostMetricsLog(it) }), + PAX(Res.string.pax_metrics_log, Res.drawable.ic_people, { NodeDetailRoute.PaxMetrics(it) }), } diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt index ce8bd665e..cca1b67bf 100644 --- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt +++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt @@ -21,8 +21,8 @@ import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import kotlinx.coroutines.flow.Flow import org.koin.compose.viewmodel.koinViewModel -import org.meshtastic.core.navigation.ChannelsRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.ChannelsRoute +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.feature.node.list.NodeListScreen import org.meshtastic.feature.node.list.NodeListViewModel @@ -37,8 +37,8 @@ fun AdaptiveNodeListScreen( NodeListScreen( viewModel = nodeListViewModel, - navigateToNodeDetails = { nodeId -> backStack.add(NodesRoutes.NodeDetail(nodeId)) }, - onNavigateToChannels = { backStack.add(ChannelsRoutes.ChannelsGraph) }, + navigateToNodeDetails = { nodeId -> backStack.add(NodesRoute.NodeDetail(nodeId)) }, + onNavigateToChannels = { backStack.add(ChannelsRoute.ChannelsGraph) }, scrollToTopEvents = scrollToTopEvents, activeNodeId = null, onHandleDeepLink = onHandleDeepLink, diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt index abfc38905..b80d7cba5 100644 --- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt +++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt @@ -28,9 +28,9 @@ import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf -import org.meshtastic.core.navigation.ContactsRoutes -import org.meshtastic.core.navigation.NodeDetailRoutes -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.ContactsRoute +import org.meshtastic.core.navigation.NodeDetailRoute +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.navigation.Route import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.device @@ -74,7 +74,7 @@ fun EntryProviderScope.nodesGraph( scrollToTopEvents: Flow = MutableSharedFlow(), onHandleDeepLink: (org.meshtastic.core.common.util.MeshtasticUri, onInvalid: () -> Unit) -> Unit = { _, _ -> }, ) { - entry(metadata = { ListDetailSceneStrategy.listPane() }) { + entry(metadata = { ListDetailSceneStrategy.listPane() }) { AdaptiveNodeListScreen( backStack = backStack, scrollToTopEvents = scrollToTopEvents, @@ -82,7 +82,7 @@ fun EntryProviderScope.nodesGraph( ) } - entry(metadata = { ListDetailSceneStrategy.listPane() }) { + entry(metadata = { ListDetailSceneStrategy.listPane() }) { AdaptiveNodeListScreen( backStack = backStack, scrollToTopEvents = scrollToTopEvents, @@ -100,7 +100,7 @@ fun EntryProviderScope.nodeDetailGraph( scrollToTopEvents: Flow, onHandleDeepLink: (org.meshtastic.core.common.util.MeshtasticUri, onInvalid: () -> Unit) -> Unit = { _, _ -> }, ) { - entry(metadata = { ListDetailSceneStrategy.listPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.listPane() }) { args -> AdaptiveNodeListScreen( backStack = backStack, scrollToTopEvents = scrollToTopEvents, @@ -108,7 +108,7 @@ fun EntryProviderScope.nodeDetailGraph( ) } - entry(metadata = { ListDetailSceneStrategy.detailPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.detailPane() }) { args -> val nodeDetailViewModel: NodeDetailViewModel = koinViewModel() val compassViewModel: CompassViewModel = koinViewModel() val destNum = args.destNum ?: 0 // Handle nullable destNum if needed @@ -116,18 +116,18 @@ fun EntryProviderScope.nodeDetailGraph( nodeId = destNum, viewModel = nodeDetailViewModel, compassViewModel = compassViewModel, - navigateToMessages = { backStack.add(ContactsRoutes.Messages(it)) }, + navigateToMessages = { backStack.add(ContactsRoute.Messages(it)) }, onNavigate = { backStack.add(it) }, onNavigateUp = { backStack.removeLastOrNull() }, ) } - entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> val mapScreen = org.meshtastic.core.ui.util.LocalNodeMapScreenProvider.current mapScreen(args.destNum) { backStack.removeLastOrNull() } } - entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> val metricsViewModel = koinViewModel { parametersOf(args.destNum) } metricsViewModel.setNodeId(args.destNum) @@ -136,7 +136,7 @@ fun EntryProviderScope.nodeDetailGraph( onNavigateUp = { backStack.removeLastOrNull() }, onViewOnMap = { requestId, responseLogUuid -> backStack.add( - NodeDetailRoutes.TracerouteMap( + NodeDetailRoute.TracerouteMap( destNum = args.destNum, requestId = requestId, logUuid = responseLogUuid, @@ -146,40 +146,40 @@ fun EntryProviderScope.nodeDetailGraph( ) } - entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> + entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> val tracerouteMapScreen = org.meshtastic.core.ui.util.LocalTracerouteMapScreenProvider.current tracerouteMapScreen(args.destNum, args.requestId, args.logUuid) { backStack.removeLastOrNull() } } - NodeDetailRoute.entries.forEach { routeInfo -> + NodeDetailScreen.entries.forEach { routeInfo -> when (routeInfo.routeClass) { - NodeDetailRoutes.DeviceMetrics::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.PositionLog::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.EnvironmentMetrics::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.SignalMetrics::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.PowerMetrics::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.HostMetricsLog::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.PaxMetrics::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } - NodeDetailRoutes.NeighborInfoLog::class -> - addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.DeviceMetrics::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.PositionLog::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.EnvironmentMetrics::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.SignalMetrics::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.PowerMetrics::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.HostMetricsLog::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.PaxMetrics::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } + NodeDetailRoute.NeighborInfoLog::class -> + addNodeDetailScreenComposable(backStack, routeInfo) { it.destNum } else -> Unit } } } -fun NavKey.isNodeDetailRoute(): Boolean = NodeDetailRoute.entries.any { this::class == it.routeClass } +fun NavKey.isNodeDetailRoute(): Boolean = NodeDetailScreen.entries.any { this::class == it.routeClass } @OptIn(ExperimentalMaterial3AdaptiveApi::class) private inline fun EntryProviderScope.addNodeDetailScreenComposable( backStack: NavBackStack, - routeInfo: NodeDetailRoute, + routeInfo: NodeDetailScreen, crossinline getDestNum: (R) -> Int, ) { entry(metadata = { ListDetailSceneStrategy.extraPane() }) { args -> @@ -192,7 +192,7 @@ private inline fun EntryProviderScope.addNodeDetailS } /** Expect declaration for the platform-specific traceroute map screen. */ -enum class NodeDetailRoute( +enum class NodeDetailScreen( val title: StringResource, val routeClass: KClass, val icon: DrawableResource? = null, @@ -200,55 +200,55 @@ enum class NodeDetailRoute( ) { DEVICE( Res.string.device, - NodeDetailRoutes.DeviceMetrics::class, + NodeDetailRoute.DeviceMetrics::class, Res.drawable.ic_router, { metricsVM, onNavigateUp -> DeviceMetricsScreen(metricsVM, onNavigateUp) }, ), POSITION_LOG( Res.string.position_log, - NodeDetailRoutes.PositionLog::class, + NodeDetailRoute.PositionLog::class, Res.drawable.ic_location_on, { metricsVM, onNavigateUp -> PositionLogScreen(metricsVM, onNavigateUp) }, ), ENVIRONMENT( Res.string.environment, - NodeDetailRoutes.EnvironmentMetrics::class, + NodeDetailRoute.EnvironmentMetrics::class, Res.drawable.ic_light_mode, { metricsVM, onNavigateUp -> EnvironmentMetricsScreen(metricsVM, onNavigateUp) }, ), SIGNAL( Res.string.signal, - NodeDetailRoutes.SignalMetrics::class, + NodeDetailRoute.SignalMetrics::class, Res.drawable.ic_cell_tower, { metricsVM, onNavigateUp -> SignalMetricsScreen(metricsVM, onNavigateUp) }, ), TRACEROUTE( Res.string.traceroute, - NodeDetailRoutes.TracerouteLog::class, + NodeDetailRoute.TracerouteLog::class, Res.drawable.ic_perm_scan_wifi, { metricsVM, onNavigateUp -> TracerouteLogScreen(viewModel = metricsVM, onNavigateUp = onNavigateUp) }, ), NEIGHBOR_INFO( Res.string.neighbor_info, - NodeDetailRoutes.NeighborInfoLog::class, + NodeDetailRoute.NeighborInfoLog::class, Res.drawable.ic_groups, { metricsVM, onNavigateUp -> NeighborInfoLogScreen(viewModel = metricsVM, onNavigateUp = onNavigateUp) }, ), POWER( Res.string.power, - NodeDetailRoutes.PowerMetrics::class, + NodeDetailRoute.PowerMetrics::class, Res.drawable.ic_power, { metricsVM, onNavigateUp -> PowerMetricsScreen(metricsVM, onNavigateUp) }, ), HOST( Res.string.host, - NodeDetailRoutes.HostMetricsLog::class, + NodeDetailRoute.HostMetricsLog::class, Res.drawable.ic_memory, { metricsVM, onNavigateUp -> HostMetricsLogScreen(metricsVM, onNavigateUp) }, ), PAX( Res.string.pax, - NodeDetailRoutes.PaxMetrics::class, + NodeDetailRoute.PaxMetrics::class, Res.drawable.ic_people, { metricsVM, onNavigateUp -> PaxMetricsScreen(metricsVM, onNavigateUp) }, ), diff --git a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt index ac5efad04..c33c3a293 100644 --- a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt @@ -41,8 +41,8 @@ import org.meshtastic.core.common.util.toDate import org.meshtastic.core.common.util.toInstant import org.meshtastic.core.common.util.toMeshtasticUri import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.navigation.WifiProvisionRoutes +import org.meshtastic.core.navigation.SettingsRoute +import org.meshtastic.core.navigation.WifiProvisionRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.bottom_nav_settings import org.meshtastic.core.resources.export_configuration @@ -233,7 +233,7 @@ fun SettingsScreen( ExpressiveSection(title = stringResource(Res.string.wifi_devices)) { ListItem(text = stringResource(Res.string.wifi_devices), leadingIcon = MeshtasticIcons.Wifi) { - onNavigate(WifiProvisionRoutes.WifiProvision()) + onNavigate(WifiProvisionRoute.WifiProvision()) } } @@ -249,7 +249,7 @@ fun SettingsScreen( excludedModulesUnlocked = excludedModulesUnlocked, onUnlockExcludedModules = { settingsViewModel.unlockExcludedModules() }, onShowAppIntro = { settingsViewModel.showAppIntro() }, - onNavigateToAbout = { onNavigate(SettingsRoutes.About) }, + onNavigateToAbout = { onNavigate(SettingsRoute.About) }, ) } } diff --git a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt index 4b9cf369d..0a35599f5 100644 --- a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt +++ b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt @@ -16,7 +16,7 @@ */ package org.meshtastic.feature.settings.navigation -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute actual fun getAboutLibrariesJson(): String = - SettingsRoutes::class.java.getResource("/aboutlibraries.json")?.readText() ?: "" + SettingsRoute::class.java.getResource("/aboutlibraries.json")?.readText() ?: "" diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt index e065de627..600554ba3 100644 --- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt +++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt @@ -19,7 +19,7 @@ package org.meshtastic.feature.settings.navigation import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.bluetooth import org.meshtastic.core.resources.channels @@ -50,43 +50,43 @@ enum class ConfigRoute( val icon: DrawableResource? = null, val type: Int = 0, ) { - USER(Res.string.user, SettingsRoutes.User, Res.drawable.ic_person, 0), - CHANNELS(Res.string.channels, SettingsRoutes.ChannelConfig, Res.drawable.ic_list, 0), + USER(Res.string.user, SettingsRoute.User, Res.drawable.ic_person, 0), + CHANNELS(Res.string.channels, SettingsRoute.ChannelConfig, Res.drawable.ic_list, 0), DEVICE( Res.string.device, - SettingsRoutes.Device, + SettingsRoute.Device, Res.drawable.ic_router, AdminMessage.ConfigType.DEVICE_CONFIG.value, ), POSITION( Res.string.position, - SettingsRoutes.Position, + SettingsRoute.Position, Res.drawable.ic_location_on, AdminMessage.ConfigType.POSITION_CONFIG.value, ), - POWER(Res.string.power, SettingsRoutes.Power, Res.drawable.ic_power, AdminMessage.ConfigType.POWER_CONFIG.value), + POWER(Res.string.power, SettingsRoute.Power, Res.drawable.ic_power, AdminMessage.ConfigType.POWER_CONFIG.value), NETWORK( Res.string.network, - SettingsRoutes.Network, + SettingsRoute.Network, Res.drawable.ic_wifi, AdminMessage.ConfigType.NETWORK_CONFIG.value, ), DISPLAY( Res.string.display, - SettingsRoutes.Display, + SettingsRoute.Display, Res.drawable.ic_display_settings, AdminMessage.ConfigType.DISPLAY_CONFIG.value, ), - LORA(Res.string.lora, SettingsRoutes.LoRa, Res.drawable.ic_cell_tower, AdminMessage.ConfigType.LORA_CONFIG.value), + LORA(Res.string.lora, SettingsRoute.LoRa, Res.drawable.ic_cell_tower, AdminMessage.ConfigType.LORA_CONFIG.value), BLUETOOTH( Res.string.bluetooth, - SettingsRoutes.Bluetooth, + SettingsRoute.Bluetooth, Res.drawable.ic_bluetooth, AdminMessage.ConfigType.BLUETOOTH_CONFIG.value, ), SECURITY( Res.string.security, - SettingsRoutes.Security, + SettingsRoute.Security, Res.drawable.ic_security, AdminMessage.ConfigType.SECURITY_CONFIG.value, ), diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt index 350ca77cc..45a41447e 100644 --- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt +++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt @@ -20,7 +20,7 @@ import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.model.Capabilities import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.ambient_lighting import org.meshtastic.core.resources.audio @@ -64,96 +64,96 @@ enum class ModuleRoute( val isSupported: (Capabilities) -> Boolean = { true }, val isApplicable: (Config.DeviceConfig.Role?) -> Boolean = { true }, ) { - MQTT(Res.string.mqtt, SettingsRoutes.MQTT, Res.drawable.ic_cloud, AdminMessage.ModuleConfigType.MQTT_CONFIG.value), + MQTT(Res.string.mqtt, SettingsRoute.MQTT, Res.drawable.ic_cloud, AdminMessage.ModuleConfigType.MQTT_CONFIG.value), SERIAL( Res.string.serial, - SettingsRoutes.Serial, + SettingsRoute.Serial, Res.drawable.ic_usb, AdminMessage.ModuleConfigType.SERIAL_CONFIG.value, ), EXT_NOTIFICATION( Res.string.external_notification, - SettingsRoutes.ExtNotification, + SettingsRoute.ExtNotification, Res.drawable.ic_notifications, AdminMessage.ModuleConfigType.EXTNOTIF_CONFIG.value, ), STORE_FORWARD( Res.string.store_forward, - SettingsRoutes.StoreForward, + SettingsRoute.StoreForward, Res.drawable.ic_terminal, AdminMessage.ModuleConfigType.STOREFORWARD_CONFIG.value, ), RANGE_TEST( Res.string.range_test, - SettingsRoutes.RangeTest, + SettingsRoute.RangeTest, Res.drawable.ic_speed, AdminMessage.ModuleConfigType.RANGETEST_CONFIG.value, ), TELEMETRY( Res.string.telemetry, - SettingsRoutes.Telemetry, + SettingsRoute.Telemetry, Res.drawable.ic_data_usage, AdminMessage.ModuleConfigType.TELEMETRY_CONFIG.value, ), CANNED_MESSAGE( Res.string.canned_message, - SettingsRoutes.CannedMessage, + SettingsRoute.CannedMessage, Res.drawable.ic_message, AdminMessage.ModuleConfigType.CANNEDMSG_CONFIG.value, ), AUDIO( Res.string.audio, - SettingsRoutes.Audio, + SettingsRoute.Audio, Res.drawable.ic_volume_up, AdminMessage.ModuleConfigType.AUDIO_CONFIG.value, ), REMOTE_HARDWARE( Res.string.remote_hardware, - SettingsRoutes.RemoteHardware, + SettingsRoute.RemoteHardware, Res.drawable.ic_settings_remote, AdminMessage.ModuleConfigType.REMOTEHARDWARE_CONFIG.value, ), NEIGHBOR_INFO( Res.string.neighbor_info, - SettingsRoutes.NeighborInfo, + SettingsRoute.NeighborInfo, Res.drawable.ic_people, AdminMessage.ModuleConfigType.NEIGHBORINFO_CONFIG.value, ), AMBIENT_LIGHTING( Res.string.ambient_lighting, - SettingsRoutes.AmbientLighting, + SettingsRoute.AmbientLighting, Res.drawable.ic_light_mode, AdminMessage.ModuleConfigType.AMBIENTLIGHTING_CONFIG.value, ), DETECTION_SENSOR( Res.string.detection_sensor, - SettingsRoutes.DetectionSensor, + SettingsRoute.DetectionSensor, Res.drawable.ic_sensors, AdminMessage.ModuleConfigType.DETECTIONSENSOR_CONFIG.value, ), PAXCOUNTER( Res.string.paxcounter, - SettingsRoutes.Paxcounter, + SettingsRoute.Paxcounter, Res.drawable.ic_perm_scan_wifi, AdminMessage.ModuleConfigType.PAXCOUNTER_CONFIG.value, ), STATUS_MESSAGE( Res.string.status_message, - SettingsRoutes.StatusMessage, + SettingsRoute.StatusMessage, Res.drawable.ic_message, AdminMessage.ModuleConfigType.STATUSMESSAGE_CONFIG.value, isSupported = { it.supportsStatusMessage }, ), TRAFFIC_MANAGEMENT( Res.string.traffic_management, - SettingsRoutes.TrafficManagement, + SettingsRoute.TrafficManagement, Res.drawable.ic_alt_route, AdminMessage.ModuleConfigType.TRAFFICMANAGEMENT_CONFIG.value, isSupported = { it.supportsTrafficManagementConfig }, ), TAK( Res.string.tak, - SettingsRoutes.TAK, + SettingsRoute.TAK, Res.drawable.ic_people, AdminMessage.ModuleConfigType.TAK_CONFIG.value, isSupported = { it.supportsTakConfig }, diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt index ac713ae7e..1409f6bdf 100644 --- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt +++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt @@ -26,9 +26,9 @@ import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import org.koin.compose.viewmodel.koinViewModel -import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.navigation.NodesRoute import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.feature.settings.AboutScreen import org.meshtastic.feature.settings.AdministrationScreen import org.meshtastic.feature.settings.DeviceConfigurationScreen @@ -74,10 +74,10 @@ fun getRadioConfigViewModel(backStack: NavBackStack): RadioConfigViewMod val viewModel = koinViewModel() val destNum = remember(backStack.toList()) { - backStack.lastOrNull { it is SettingsRoutes.Settings }?.let { (it as SettingsRoutes.Settings).destNum } + backStack.lastOrNull { it is SettingsRoute.Settings }?.let { (it as SettingsRoute.Settings).destNum } ?: backStack - .lastOrNull { it is SettingsRoutes.SettingsGraph } - ?.let { (it as SettingsRoutes.SettingsGraph).destNum } + .lastOrNull { it is SettingsRoute.SettingsGraph } + ?.let { (it as SettingsRoute.SettingsGraph).destNum } } SideEffect { viewModel.initDestNum(destNum) } return viewModel @@ -85,25 +85,25 @@ fun getRadioConfigViewModel(backStack: NavBackStack): RadioConfigViewMod @Suppress("LongMethod", "CyclomaticComplexMethod") fun EntryProviderScope.settingsGraph(backStack: NavBackStack) { - entry { + entry { SettingsMainScreen( settingsViewModel = koinViewModel(), radioConfigViewModel = getRadioConfigViewModel(backStack), - onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) }, + onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) }, onNavigate = { backStack.add(it) }, ) } - entry { + entry { SettingsMainScreen( settingsViewModel = koinViewModel(), radioConfigViewModel = getRadioConfigViewModel(backStack), - onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) }, + onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) }, onNavigate = { backStack.add(it) }, ) } - entry { + entry { DeviceConfigurationScreen( viewModel = getRadioConfigViewModel(backStack), onBack = { backStack.removeLastOrNull() }, @@ -111,7 +111,7 @@ fun EntryProviderScope.settingsGraph(backStack: NavBackStack) { ) } - entry { + entry { val settingsViewModel: SettingsViewModel = koinViewModel() val excludedModulesUnlocked by settingsViewModel.excludedModulesUnlocked.collectAsStateWithLifecycle() ModuleConfigurationScreen( @@ -122,11 +122,11 @@ fun EntryProviderScope.settingsGraph(backStack: NavBackStack) { ) } - entry { + entry { AdministrationScreen(viewModel = getRadioConfigViewModel(backStack), onBack = { backStack.removeLastOrNull() }) } - entry { + entry { val viewModel: CleanNodeDatabaseViewModel = koinViewModel() CleanNodeDatabaseScreen(viewModel = viewModel) } @@ -185,16 +185,16 @@ fun EntryProviderScope.settingsGraph(backStack: NavBackStack) { } } - entry { + entry { val viewModel: DebugViewModel = koinViewModel() DebugScreen(viewModel = viewModel, onNavigateUp = { backStack.removeLastOrNull() }) } - entry { + entry { AboutScreen(onNavigateUp = { backStack.removeLastOrNull() }, jsonProvider = { getAboutLibrariesJson() }) } - entry { + entry { val viewModel: FilterSettingsViewModel = koinViewModel() FilterSettingsScreen(viewModel = viewModel, onBack = { backStack.removeLastOrNull() }) } diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt index 4fb2fa41a..768895327 100644 --- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt +++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt @@ -28,9 +28,9 @@ import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.vectorResource -import org.meshtastic.core.navigation.FirmwareRoutes +import org.meshtastic.core.navigation.FirmwareRoute import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.administration import org.meshtastic.core.resources.advanced_title @@ -125,7 +125,7 @@ private fun DeviceConfigSection(isManaged: Boolean, enabled: Boolean, onNavigate trailingIcon = MeshtasticIcons.KeyboardArrowRight, enabled = enabled, ) { - onNavigate(SettingsRoutes.DeviceConfiguration) + onNavigate(SettingsRoute.DeviceConfiguration) } } } @@ -142,7 +142,7 @@ private fun ModuleSettingsSection(isManaged: Boolean, enabled: Boolean, onNaviga trailingIcon = MeshtasticIcons.KeyboardArrowRight, enabled = enabled, ) { - onNavigate(SettingsRoutes.ModuleConfiguration) + onNavigate(SettingsRoute.ModuleConfiguration) } } } @@ -181,7 +181,7 @@ private fun AdministrationSection(enabled: Boolean, onNavigate: (Route) -> Unit) trailingIconTint = MaterialTheme.colorScheme.error, enabled = enabled, ) { - onNavigate(SettingsRoutes.Administration) + onNavigate(SettingsRoute.Administration) } } } @@ -198,7 +198,7 @@ private fun AdvancedSection(isManaged: Boolean, isOtaCapable: Boolean, enabled: text = stringResource(Res.string.firmware_update_title), leadingIcon = MeshtasticIcons.SystemUpdate, enabled = enabled, - onClick = { onNavigate(FirmwareRoutes.FirmwareUpdate) }, + onClick = { onNavigate(FirmwareRoute.FirmwareUpdate) }, ) } @@ -206,14 +206,14 @@ private fun AdvancedSection(isManaged: Boolean, isOtaCapable: Boolean, enabled: text = stringResource(Res.string.clean_node_database_title), leadingIcon = MeshtasticIcons.CleaningServices, enabled = enabled, - onClick = { onNavigate(SettingsRoutes.CleanNodeDb) }, + onClick = { onNavigate(SettingsRoute.CleanNodeDb) }, ) ListItem( text = stringResource(Res.string.debug_panel), leadingIcon = MeshtasticIcons.BugReport, enabled = enabled, - onClick = { onNavigate(SettingsRoutes.DebugPanel) }, + onClick = { onNavigate(SettingsRoute.DebugPanel) }, ) } } diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt index 9966ca24e..f73b6b731 100644 --- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt +++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt @@ -20,12 +20,12 @@ import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import org.koin.compose.viewmodel.koinViewModel -import org.meshtastic.core.navigation.ChannelsRoutes +import org.meshtastic.core.navigation.ChannelsRoute import org.meshtastic.feature.settings.radio.RadioConfigViewModel -/** Navigation graph for for the top level ChannelScreen - [ChannelsRoutes.Channels]. */ +/** Navigation graph for for the top level ChannelScreen - [ChannelsRoute.Channels]. */ fun EntryProviderScope.channelsGraph(backStack: NavBackStack) { - entry { + entry { ChannelScreen( radioConfigViewModel = koinViewModel(), onNavigate = { route -> backStack.add(route) }, @@ -33,7 +33,7 @@ fun EntryProviderScope.channelsGraph(backStack: NavBackStack) { ) } - entry { + entry { ChannelScreen( radioConfigViewModel = koinViewModel(), onNavigate = { route -> backStack.add(route) }, diff --git a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt index 21cb3b09f..3ebe556b0 100644 --- a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt +++ b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt @@ -39,8 +39,8 @@ import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.DatabaseConstants import org.meshtastic.core.navigation.Route -import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.navigation.WifiProvisionRoutes +import org.meshtastic.core.navigation.SettingsRoute +import org.meshtastic.core.navigation.WifiProvisionRoute import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.acknowledgements import org.meshtastic.core.resources.app_settings @@ -202,7 +202,7 @@ fun DesktopSettingsScreen( ExpressiveSection(title = stringResource(Res.string.wifi_devices)) { ListItem(text = stringResource(Res.string.wifi_devices), leadingIcon = MeshtasticIcons.Wifi) { - onNavigate(WifiProvisionRoutes.WifiProvision()) + onNavigate(WifiProvisionRoute.WifiProvision()) } } @@ -219,7 +219,7 @@ fun DesktopSettingsScreen( appVersionName = settingsViewModel.appVersionName, excludedModulesUnlocked = excludedModulesUnlocked, onUnlockExcludedModules = { settingsViewModel.unlockExcludedModules() }, - onNavigateToAbout = { onNavigate(SettingsRoutes.About) }, + onNavigateToAbout = { onNavigate(SettingsRoute.About) }, ) } } diff --git a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt index 4b9cf369d..0a35599f5 100644 --- a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt +++ b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt @@ -16,7 +16,7 @@ */ package org.meshtastic.feature.settings.navigation -import org.meshtastic.core.navigation.SettingsRoutes +import org.meshtastic.core.navigation.SettingsRoute actual fun getAboutLibrariesJson(): String = - SettingsRoutes::class.java.getResource("/aboutlibraries.json")?.readText() ?: "" + SettingsRoute::class.java.getResource("/aboutlibraries.json")?.readText() ?: "" diff --git a/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt b/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt index 472f1effe..ea30112c7 100644 --- a/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt +++ b/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt @@ -19,21 +19,21 @@ package org.meshtastic.feature.wifiprovision.navigation import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey -import org.meshtastic.core.navigation.WifiProvisionRoutes +import org.meshtastic.core.navigation.WifiProvisionRoute import org.meshtastic.feature.wifiprovision.ui.WifiProvisionScreen /** * Registers the WiFi provisioning graph entries into the host navigation provider. * - * Both the graph sentinel ([WifiProvisionRoutes.WifiProvisionGraph]) and the primary screen - * ([WifiProvisionRoutes.WifiProvision]) navigate to the same composable so that the feature can be reached via either a + * Both the graph sentinel ([WifiProvisionRoute.WifiProvisionGraph]) and the primary screen + * ([WifiProvisionRoute.WifiProvision]) navigate to the same composable so that the feature can be reached via either a * top-level push or a deep-link graph push. */ fun EntryProviderScope.wifiProvisionGraph(backStack: NavBackStack) { - entry { + entry { WifiProvisionScreen(onNavigateUp = { backStack.removeLastOrNull() }) } - entry { key -> + entry { key -> WifiProvisionScreen(onNavigateUp = { backStack.removeLastOrNull() }, address = key.address) } }