diff --git a/app/src/main/java/com/geeksville/mesh/navigation/NodeDetailNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/NodeDetailNavigation.kt
new file mode 100644
index 000000000..76796cb70
--- /dev/null
+++ b/app/src/main/java/com/geeksville/mesh/navigation/NodeDetailNavigation.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2025 Meshtastic LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.geeksville.mesh.navigation
+
+import androidx.compose.runtime.remember
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import com.geeksville.mesh.model.MetricsViewModel
+import com.geeksville.mesh.ui.NodeDetailScreen
+import com.geeksville.mesh.ui.components.DeviceMetricsScreen
+import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen
+import com.geeksville.mesh.ui.components.NodeMapScreen
+import com.geeksville.mesh.ui.components.PositionLogScreen
+import com.geeksville.mesh.ui.components.SignalMetricsScreen
+import com.geeksville.mesh.ui.components.TracerouteLogScreen
+
+fun NavGraphBuilder.addNodDetailSection(navController: NavController) {
+ composable {
+ NodeDetailScreen(
+ onNavigate = navController::navigate,
+ )
+ }
+ composable {
+ val parentEntry = remember { navController.getBackStackEntry() }
+ DeviceMetricsScreen(
+ viewModel = hiltViewModel(parentEntry),
+ )
+ }
+ composable {
+ val parentEntry = remember { navController.getBackStackEntry() }
+ NodeMapScreen(
+ viewModel = hiltViewModel(parentEntry),
+ )
+ }
+ composable {
+ val parentEntry = remember { navController.getBackStackEntry() }
+ PositionLogScreen(
+ viewModel = hiltViewModel(parentEntry),
+ )
+ }
+ composable {
+ val parentEntry = remember { navController.getBackStackEntry() }
+ EnvironmentMetricsScreen(
+ viewModel = hiltViewModel(parentEntry),
+ )
+ }
+ composable {
+ val parentEntry = remember { navController.getBackStackEntry() }
+ SignalMetricsScreen(
+ viewModel = hiltViewModel(parentEntry),
+ )
+ }
+ composable {
+ val parentEntry = remember { navController.getBackStackEntry() }
+ TracerouteLogScreen(
+ viewModel = hiltViewModel(parentEntry),
+ )
+ }
+}
diff --git a/app/src/main/java/com/geeksville/mesh/navigation/ShareNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/ShareNavigation.kt
new file mode 100644
index 000000000..3dd68e211
--- /dev/null
+++ b/app/src/main/java/com/geeksville/mesh/navigation/ShareNavigation.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025 Meshtastic LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.geeksville.mesh.navigation
+
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import androidx.navigation.toRoute
+import com.geeksville.mesh.ui.ShareScreen
+
+fun NavController.navigateToSharedMessage(contactKey: String, message: String) {
+ navigate(Route.Messages(contactKey, message)) {
+ popUpTo { inclusive = true }
+ }
+}
+
+fun NavGraphBuilder.shareScreen(
+ navigateUp: () -> Unit,
+ onConfirm: (String, String) -> Unit
+) {
+ composable { backStackEntry ->
+ val message = backStackEntry.toRoute().message
+ ShareScreen(
+ navigateUp = navigateUp,
+ ) { contactKey -> onConfirm(contactKey, message) }
+ }
+}
diff --git a/app/src/main/java/com/geeksville/mesh/ui/NavGraph.kt b/app/src/main/java/com/geeksville/mesh/ui/NavGraph.kt
index aecc8d377..4eae460b4 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/NavGraph.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/NavGraph.kt
@@ -23,7 +23,6 @@ import android.view.View
import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
@@ -31,25 +30,18 @@ import androidx.compose.ui.res.stringResource
import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
-import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
-import androidx.navigation.toRoute
import com.geeksville.mesh.R
import com.geeksville.mesh.android.Logging
-import com.geeksville.mesh.model.MetricsViewModel
import com.geeksville.mesh.navigation.Route
+import com.geeksville.mesh.navigation.addNodDetailSection
import com.geeksville.mesh.navigation.addRadioConfigSection
+import com.geeksville.mesh.navigation.navigateToSharedMessage
+import com.geeksville.mesh.navigation.shareScreen
import com.geeksville.mesh.ui.components.BaseScaffold
-import com.geeksville.mesh.ui.components.DeviceMetricsScreen
-import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen
-import com.geeksville.mesh.ui.components.NodeMapScreen
-import com.geeksville.mesh.ui.components.PositionLogScreen
-import com.geeksville.mesh.ui.components.SignalMetricsScreen
-import com.geeksville.mesh.ui.components.TracerouteLogScreen
import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel
import com.geeksville.mesh.ui.theme.AppTheme
import dagger.hilt.android.AndroidEntryPoint
@@ -125,43 +117,11 @@ fun NavGraph(
startDestination = startDestination,
modifier = modifier,
) {
- composable {
- NodeDetailScreen { navController.navigate(route = it) }
- }
- composable {
- val parentEntry = remember { navController.getBackStackEntry() }
- DeviceMetricsScreen(hiltViewModel(parentEntry))
- }
- composable {
- val parentEntry = remember { navController.getBackStackEntry() }
- NodeMapScreen(hiltViewModel(parentEntry))
- }
- composable {
- val parentEntry = remember { navController.getBackStackEntry() }
- PositionLogScreen(hiltViewModel(parentEntry))
- }
- composable {
- val parentEntry = remember { navController.getBackStackEntry() }
- EnvironmentMetricsScreen(hiltViewModel(parentEntry))
- }
- composable {
- val parentEntry = remember { navController.getBackStackEntry() }
- SignalMetricsScreen(hiltViewModel(parentEntry))
- }
- composable {
- val parentEntry = remember { navController.getBackStackEntry() }
- TracerouteLogScreen(hiltViewModel(parentEntry))
- }
+ addNodDetailSection(navController)
addRadioConfigSection(navController)
- composable { backStackEntry ->
- val message = backStackEntry.toRoute().message
- ShareScreen(
- navigateUp = navController::navigateUp,
- ) {
- navController.navigate(Route.Messages(it, message)) {
- popUpTo { inclusive = true }
- }
- }
- }
+ shareScreen(
+ navigateUp = navController::navigateUp,
+ onConfirm = navController::navigateToSharedMessage,
+ )
}
}