diff --git a/app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt b/app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt index 9a4e1b2c3..33a55bc0b 100644 --- a/app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt +++ b/app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt @@ -27,7 +27,7 @@ import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile import com.geeksville.mesh.R import com.geeksville.mesh.deviceProfile import com.geeksville.mesh.position -import com.geeksville.mesh.ui.components.config.EditDeviceProfileDialog +import com.geeksville.mesh.ui.radioconfig.components.EditDeviceProfileDialog import org.junit.Assert import org.junit.Rule import org.junit.Test diff --git a/app/src/main/java/com/geeksville/mesh/navigation/RadioConfigNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/RadioConfigNavigation.kt new file mode 100644 index 000000000..4323b2212 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/navigation/RadioConfigNavigation.kt @@ -0,0 +1,197 @@ +/* + * 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.ui.Route +import com.geeksville.mesh.ui.radioconfig.RadioConfigScreen +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel +import com.geeksville.mesh.ui.radioconfig.components.AmbientLightingConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.AudioConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.BluetoothConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.CannedMessageConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.ChannelConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.DetectionSensorConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.DeviceConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.DisplayConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.ExternalNotificationConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.LoRaConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.MQTTConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.NeighborInfoConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.NetworkConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.PaxcounterConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.PositionConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.PowerConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.RangeTestConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.RemoteHardwareConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.SecurityConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.SerialConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.StoreForwardConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.TelemetryConfigScreen +import com.geeksville.mesh.ui.radioconfig.components.UserConfigScreen + +@Suppress("LongMethod") +fun NavGraphBuilder.addRadioConfigSection(navController: NavController) { + composable { + RadioConfigScreen( + onNavigate = navController::navigate, + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + UserConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + ChannelConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + DeviceConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + PositionConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + PowerConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + NetworkConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + DisplayConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + LoRaConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + BluetoothConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + SecurityConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + MQTTConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + SerialConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + ExternalNotificationConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + StoreForwardConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + RangeTestConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + TelemetryConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + CannedMessageConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + AudioConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + RemoteHardwareConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + NeighborInfoConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + AmbientLightingConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + DetectionSensorConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } + composable { + val parentEntry = remember { navController.getBackStackEntry() } + PaxcounterConfigScreen( + viewModel = hiltViewModel(parentEntry), + ) + } +} diff --git a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt index d2b020028..a55054b84 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt @@ -104,12 +104,12 @@ import com.geeksville.mesh.service.MeshService import com.geeksville.mesh.ui.components.AdaptiveTwoPane import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.PreferenceFooter -import com.geeksville.mesh.ui.components.config.ChannelCard -import com.geeksville.mesh.ui.components.config.ChannelSelection -import com.geeksville.mesh.ui.components.config.EditChannelDialog import com.geeksville.mesh.ui.components.dragContainer import com.geeksville.mesh.ui.components.dragDropItemsIndexed import com.geeksville.mesh.ui.components.rememberDragDropState +import com.geeksville.mesh.ui.radioconfig.components.ChannelCard +import com.geeksville.mesh.ui.radioconfig.components.ChannelSelection +import com.geeksville.mesh.ui.radioconfig.components.EditChannelDialog import com.geeksville.mesh.ui.theme.AppTheme import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.journeyapps.barcodescanner.ScanContract 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 6f7e5ba8e..b98546fde 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/NavGraph.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/NavGraph.kt @@ -21,36 +21,10 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.annotation.StringRes -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Forward -import androidx.compose.material.icons.automirrored.filled.List -import androidx.compose.material.icons.automirrored.filled.Message -import androidx.compose.material.icons.automirrored.filled.VolumeUp -import androidx.compose.material.icons.filled.Bluetooth -import androidx.compose.material.icons.filled.CellTower -import androidx.compose.material.icons.filled.Cloud -import androidx.compose.material.icons.filled.DataUsage -import androidx.compose.material.icons.filled.DisplaySettings -import androidx.compose.material.icons.filled.LightMode -import androidx.compose.material.icons.filled.LocationOn -import androidx.compose.material.icons.filled.Notifications -import androidx.compose.material.icons.filled.People -import androidx.compose.material.icons.filled.PermScanWifi -import androidx.compose.material.icons.filled.Person -import androidx.compose.material.icons.filled.Power -import androidx.compose.material.icons.filled.Router -import androidx.compose.material.icons.filled.Security -import androidx.compose.material.icons.filled.Sensors -import androidx.compose.material.icons.filled.SettingsRemote -import androidx.compose.material.icons.filled.Speed -import androidx.compose.material.icons.filled.Usb -import androidx.compose.material.icons.filled.Wifi import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.res.stringResource @@ -64,11 +38,10 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.toRoute -import com.geeksville.mesh.MeshProtos.DeviceMetadata import com.geeksville.mesh.R import com.geeksville.mesh.android.Logging import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.model.RadioConfigViewModel +import com.geeksville.mesh.navigation.addRadioConfigSection import com.geeksville.mesh.ui.components.BaseScaffold import com.geeksville.mesh.ui.components.DeviceMetricsScreen import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen @@ -76,31 +49,8 @@ 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.components.config.AmbientLightingConfigScreen -import com.geeksville.mesh.ui.components.config.AudioConfigScreen -import com.geeksville.mesh.ui.components.config.BluetoothConfigScreen -import com.geeksville.mesh.ui.components.config.CannedMessageConfigScreen -import com.geeksville.mesh.ui.components.config.ChannelConfigScreen -import com.geeksville.mesh.ui.components.config.DetectionSensorConfigScreen -import com.geeksville.mesh.ui.components.config.DeviceConfigScreen -import com.geeksville.mesh.ui.components.config.DisplayConfigScreen -import com.geeksville.mesh.ui.components.config.ExternalNotificationConfigScreen -import com.geeksville.mesh.ui.components.config.LoRaConfigScreen -import com.geeksville.mesh.ui.components.config.MQTTConfigScreen -import com.geeksville.mesh.ui.components.config.NeighborInfoConfigScreen -import com.geeksville.mesh.ui.components.config.NetworkConfigScreen -import com.geeksville.mesh.ui.components.config.PaxcounterConfigScreen -import com.geeksville.mesh.ui.components.config.PositionConfigScreen -import com.geeksville.mesh.ui.components.config.PowerConfigScreen -import com.geeksville.mesh.ui.components.config.RangeTestConfigScreen -import com.geeksville.mesh.ui.components.config.RemoteHardwareConfigScreen -import com.geeksville.mesh.ui.components.config.SecurityConfigScreen -import com.geeksville.mesh.ui.components.config.SerialConfigScreen -import com.geeksville.mesh.ui.components.config.StoreForwardConfigScreen -import com.geeksville.mesh.ui.components.config.TelemetryConfigScreen -import com.geeksville.mesh.ui.components.config.UserConfigScreen +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel import com.geeksville.mesh.ui.theme.AppTheme -import com.geeksville.mesh.util.UiText import dagger.hilt.android.AndroidEntryPoint import kotlinx.serialization.Serializable @@ -164,13 +114,6 @@ class NavGraphFragment : ScreenFragment("NavGraph"), Logging { } } -enum class AdminRoute(@StringRes val title: Int) { - REBOOT(R.string.reboot), - SHUTDOWN(R.string.shutdown), - FACTORY_RESET(R.string.factory_reset), - NODEDB_RESET(R.string.nodedb_reset), -} - sealed interface Route { @Serializable data class Messages(val contactKey: String, val message: String = "") : Route @@ -180,7 +123,7 @@ sealed interface Route { @Serializable data class RadioConfig(val destNum: Int? = null) : Route @Serializable data object User : Route - @Serializable data object Channels : Route + @Serializable data object ChannelConfig : Route @Serializable data object Device : Route @Serializable data object Position : Route @Serializable data object Power : Route @@ -214,74 +157,6 @@ sealed interface Route { @Serializable data object TracerouteLog : Route } -// Config (type = AdminProtos.AdminMessage.ConfigType) -enum class ConfigRoute(val title: String, val route: Route, val icon: ImageVector?, val type: Int = 0) { - USER("User", Route.User, Icons.Default.Person, 0), - CHANNELS("Channels", Route.Channels, Icons.AutoMirrored.Default.List, 0), - DEVICE("Device", Route.Device, Icons.Default.Router, 0), - POSITION("Position", Route.Position, Icons.Default.LocationOn, 1), - POWER("Power", Route.Power, Icons.Default.Power, 2), - NETWORK("Network", Route.Network, Icons.Default.Wifi, 3), - DISPLAY("Display", Route.Display, Icons.Default.DisplaySettings, 4), - LORA("LoRa", Route.LoRa, Icons.Default.CellTower, 5), - BLUETOOTH("Bluetooth", Route.Bluetooth, Icons.Default.Bluetooth, 6), - SECURITY("Security", Route.Security, Icons.Default.Security, type = 7), - ; - - companion object { - fun filterExcludedFrom(metadata: DeviceMetadata?): List = entries.filter { - when { - metadata == null -> true - it == BLUETOOTH -> metadata.hasBluetooth - it == NETWORK -> metadata.hasWifi || metadata.hasEthernet - else -> true // Include all other routes by default - } - } - } -} - -// ModuleConfig (type = AdminProtos.AdminMessage.ModuleConfigType) -enum class ModuleRoute(val title: String, val route: Route, val icon: ImageVector?, val type: Int = 0) { - MQTT("MQTT", Route.MQTT, Icons.Default.Cloud, 0), - SERIAL("Serial", Route.Serial, Icons.Default.Usb, 1), - EXT_NOTIFICATION("External Notification", Route.ExtNotification, Icons.Default.Notifications, 2), - STORE_FORWARD("Store & Forward", Route.StoreForward, Icons.AutoMirrored.Default.Forward, 3), - RANGE_TEST("Range Test", Route.RangeTest, Icons.Default.Speed, 4), - TELEMETRY("Telemetry", Route.Telemetry, Icons.Default.DataUsage, 5), - CANNED_MESSAGE("Canned Message", Route.CannedMessage, Icons.AutoMirrored.Default.Message, 6), - AUDIO("Audio", Route.Audio, Icons.AutoMirrored.Default.VolumeUp, 7), - REMOTE_HARDWARE("Remote Hardware", Route.RemoteHardware, Icons.Default.SettingsRemote, 8), - NEIGHBOR_INFO("Neighbor Info", Route.NeighborInfo, Icons.Default.People, 9), - AMBIENT_LIGHTING("Ambient Lighting", Route.AmbientLighting, Icons.Default.LightMode, 10), - DETECTION_SENSOR("Detection Sensor", Route.DetectionSensor, Icons.Default.Sensors, 11), - PAXCOUNTER("Paxcounter", Route.Paxcounter, Icons.Default.PermScanWifi, 12), - ; - - val bitfield: Int get() = 1 shl ordinal - - companion object { - fun filterExcludedFrom(metadata: DeviceMetadata?): List = entries.filter { - when (metadata) { - null -> true - else -> metadata.excludedModules and it.bitfield == 0 - } - } - } -} - -/** - * Generic sealed class defines each possible state of a response. - */ -sealed class ResponseState { - data object Empty : ResponseState() - data class Loading(var total: Int = 1, var completed: Int = 0) : ResponseState() - data class Success(val result: T) : ResponseState() - data class Error(val error: UiText) : ResponseState() - - fun isWaiting() = this !is Empty -} - -@Suppress("LongMethod") @Composable fun NavGraph( navController: NavHostController = rememberNavController(), @@ -320,101 +195,7 @@ fun NavGraph( val parentEntry = remember { navController.getBackStackEntry() } TracerouteLogScreen(hiltViewModel(parentEntry)) } - composable { - RadioConfigScreen { navController.navigate(route = it) } - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - UserConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - ChannelConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - DeviceConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - PositionConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - PowerConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - NetworkConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - DisplayConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - LoRaConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - BluetoothConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - SecurityConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - MQTTConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - SerialConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - ExternalNotificationConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - StoreForwardConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - RangeTestConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - TelemetryConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - CannedMessageConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - AudioConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - RemoteHardwareConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - NeighborInfoConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - AmbientLightingConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - DetectionSensorConfigScreen(hiltViewModel(parentEntry)) - } - composable { - val parentEntry = remember { navController.getBackStackEntry() } - PaxcounterConfigScreen(hiltViewModel(parentEntry)) - } + addRadioConfigSection(navController) composable { backStackEntry -> val message = backStackEntry.toRoute().message ShareScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/NodeDetail.kt b/app/src/main/java/com/geeksville/mesh/ui/NodeDetail.kt index 8a4e65298..f11bcdf36 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/NodeDetail.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/NodeDetail.kt @@ -97,6 +97,7 @@ import com.geeksville.mesh.model.MetricsViewModel import com.geeksville.mesh.model.Node import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.preview.NodePreviewParameterProvider +import com.geeksville.mesh.ui.radioconfig.NavCard import com.geeksville.mesh.ui.theme.AppTheme import com.geeksville.mesh.util.DistanceUnit import com.geeksville.mesh.util.formatAgo diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/ScannedQrCodeDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/components/ScannedQrCodeDialog.kt index 2b16eb23c..cff710a74 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/ScannedQrCodeDialog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/ScannedQrCodeDialog.kt @@ -54,7 +54,7 @@ import com.geeksville.mesh.R import com.geeksville.mesh.channelSet import com.geeksville.mesh.copy import com.geeksville.mesh.model.Channel -import com.geeksville.mesh.ui.components.config.ChannelSelection +import com.geeksville.mesh.ui.radioconfig.components.ChannelSelection /** * Enables the user to select which channels to accept after scanning a QR code. diff --git a/app/src/main/java/com/geeksville/mesh/ui/radioconfig/AdminRoute.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/AdminRoute.kt new file mode 100644 index 000000000..1ff2bd348 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/AdminRoute.kt @@ -0,0 +1,28 @@ +/* + * 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.ui.radioconfig + +import androidx.annotation.StringRes +import com.geeksville.mesh.R + +enum class AdminRoute(@StringRes val title: Int) { + REBOOT(R.string.reboot), + SHUTDOWN(R.string.shutdown), + FACTORY_RESET(R.string.factory_reset), + NODEDB_RESET(R.string.nodedb_reset), +} diff --git a/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ConfigRoute.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ConfigRoute.kt new file mode 100644 index 000000000..4f2986c37 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ConfigRoute.kt @@ -0,0 +1,60 @@ +/* + * 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.ui.radioconfig + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.List +import androidx.compose.material.icons.filled.Bluetooth +import androidx.compose.material.icons.filled.CellTower +import androidx.compose.material.icons.filled.DisplaySettings +import androidx.compose.material.icons.filled.LocationOn +import androidx.compose.material.icons.filled.Person +import androidx.compose.material.icons.filled.Power +import androidx.compose.material.icons.filled.Router +import androidx.compose.material.icons.filled.Security +import androidx.compose.material.icons.filled.Wifi +import androidx.compose.ui.graphics.vector.ImageVector +import com.geeksville.mesh.MeshProtos.DeviceMetadata +import com.geeksville.mesh.ui.Route + +@Suppress("MagicNumber") +// Config (type = AdminProtos.AdminMessage.ConfigType) +enum class ConfigRoute(val title: String, val route: Route, val icon: ImageVector?, val type: Int = 0) { + USER("User", Route.User, Icons.Default.Person, 0), + CHANNELS("Channels", Route.ChannelConfig, Icons.AutoMirrored.Default.List, 0), + DEVICE("Device", Route.Device, Icons.Default.Router, 0), + POSITION("Position", Route.Position, Icons.Default.LocationOn, 1), + POWER("Power", Route.Power, Icons.Default.Power, 2), + NETWORK("Network", Route.Network, Icons.Default.Wifi, 3), + DISPLAY("Display", Route.Display, Icons.Default.DisplaySettings, 4), + LORA("LoRa", Route.LoRa, Icons.Default.CellTower, 5), + BLUETOOTH("Bluetooth", Route.Bluetooth, Icons.Default.Bluetooth, 6), + SECURITY("Security", Route.Security, Icons.Default.Security, 7), + ; + + companion object { + fun filterExcludedFrom(metadata: DeviceMetadata?): List = entries.filter { + when { + metadata == null -> true + it == BLUETOOTH -> metadata.hasBluetooth + it == NETWORK -> metadata.hasWifi || metadata.hasEthernet + else -> true // Include all other routes by default + } + } + } +} diff --git a/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ModuleRoute.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ModuleRoute.kt new file mode 100644 index 000000000..cd6dc09da --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ModuleRoute.kt @@ -0,0 +1,66 @@ +/* + * 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.ui.radioconfig + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.Forward +import androidx.compose.material.icons.automirrored.filled.Message +import androidx.compose.material.icons.automirrored.filled.VolumeUp +import androidx.compose.material.icons.filled.Cloud +import androidx.compose.material.icons.filled.DataUsage +import androidx.compose.material.icons.filled.LightMode +import androidx.compose.material.icons.filled.Notifications +import androidx.compose.material.icons.filled.People +import androidx.compose.material.icons.filled.PermScanWifi +import androidx.compose.material.icons.filled.Sensors +import androidx.compose.material.icons.filled.SettingsRemote +import androidx.compose.material.icons.filled.Speed +import androidx.compose.material.icons.filled.Usb +import androidx.compose.ui.graphics.vector.ImageVector +import com.geeksville.mesh.MeshProtos.DeviceMetadata +import com.geeksville.mesh.ui.Route + +@Suppress("MagicNumber") +// ModuleConfig (type = AdminProtos.AdminMessage.ModuleConfigType) +enum class ModuleRoute(val title: String, val route: Route, val icon: ImageVector?, val type: Int = 0) { + MQTT("MQTT", Route.MQTT, Icons.Default.Cloud, 0), + SERIAL("Serial", Route.Serial, Icons.Default.Usb, 1), + EXT_NOTIFICATION("External Notification", Route.ExtNotification, Icons.Default.Notifications, 2), + STORE_FORWARD("Store & Forward", Route.StoreForward, Icons.AutoMirrored.Default.Forward, 3), + RANGE_TEST("Range Test", Route.RangeTest, Icons.Default.Speed, 4), + TELEMETRY("Telemetry", Route.Telemetry, Icons.Default.DataUsage, 5), + CANNED_MESSAGE("Canned Message", Route.CannedMessage, Icons.AutoMirrored.Default.Message, 6), + AUDIO("Audio", Route.Audio, Icons.AutoMirrored.Default.VolumeUp, 7), + REMOTE_HARDWARE("Remote Hardware", Route.RemoteHardware, Icons.Default.SettingsRemote, 8), + NEIGHBOR_INFO("Neighbor Info", Route.NeighborInfo, Icons.Default.People, 9), + AMBIENT_LIGHTING("Ambient Lighting", Route.AmbientLighting, Icons.Default.LightMode, 10), + DETECTION_SENSOR("Detection Sensor", Route.DetectionSensor, Icons.Default.Sensors, 11), + PAXCOUNTER("Paxcounter", Route.Paxcounter, Icons.Default.PermScanWifi, 12), + ; + + val bitfield: Int get() = 1 shl ordinal + + companion object { + fun filterExcludedFrom(metadata: DeviceMetadata?): List = entries.filter { + when (metadata) { + null -> true + else -> metadata.excludedModules and it.bitfield == 0 + } + } + } +} diff --git a/app/src/main/java/com/geeksville/mesh/ui/RadioConfigScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfig.kt similarity index 82% rename from app/src/main/java/com/geeksville/mesh/ui/RadioConfigScreen.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfig.kt index 527d6a96f..2889338f7 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/RadioConfigScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfig.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui +package com.geeksville.mesh.ui.radioconfig import android.app.Activity import android.content.Intent @@ -65,13 +65,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile import com.geeksville.mesh.R -import com.geeksville.mesh.model.RadioConfigState -import com.geeksville.mesh.model.RadioConfigViewModel +import com.geeksville.mesh.ui.Route import com.geeksville.mesh.ui.components.PreferenceCategory -import com.geeksville.mesh.ui.components.config.EditDeviceProfileDialog -import com.geeksville.mesh.ui.components.config.PacketResponseStateDialog +import com.geeksville.mesh.ui.radioconfig.components.EditDeviceProfileDialog +import com.geeksville.mesh.ui.radioconfig.components.PacketResponseStateDialog -private fun getNavRouteFrom(routeName: String): Any? { +private fun getNavRouteFrom(routeName: String): Route? { return ConfigRoute.entries.find { it.name == routeName }?.route ?: ModuleRoute.entries.find { it.name == routeName }?.route } @@ -81,7 +80,7 @@ private fun getNavRouteFrom(routeName: String): Any? { fun RadioConfigScreen( viewModel: RadioConfigViewModel = hiltViewModel(), modifier: Modifier = Modifier, - onNavigate: (Any) -> Unit = {} + onNavigate: (Route) -> Unit = {} ) { val state by viewModel.radioConfigState.collectAsStateWithLifecycle() var isWaiting by remember { mutableStateOf(false) } @@ -222,54 +221,57 @@ fun NavCard( } } +@Suppress("LongMethod") @Composable private fun NavButton(@StringRes title: Int, enabled: Boolean, onClick: () -> Unit) { var showDialog by remember { mutableStateOf(false) } - if (showDialog) AlertDialog( - onDismissRequest = {}, - shape = RoundedCornerShape(16.dp), - backgroundColor = MaterialTheme.colors.background, - title = { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center, - ) { - Icon( - imageVector = Icons.TwoTone.Warning, - contentDescription = "warning", - modifier = Modifier.padding(end = 8.dp) - ) - Text( - text = "${stringResource(title)}?\n") - Icon( - imageVector = Icons.TwoTone.Warning, - contentDescription = "warning", - modifier = Modifier.padding(start = 8.dp) - ) + if (showDialog) { + AlertDialog( + onDismissRequest = {}, + shape = RoundedCornerShape(16.dp), + backgroundColor = MaterialTheme.colors.background, + title = { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Center, + ) { + Icon( + imageVector = Icons.TwoTone.Warning, + contentDescription = "warning", + modifier = Modifier.padding(end = 8.dp) + ) + Text( + text = "${stringResource(title)}?\n") + Icon( + imageVector = Icons.TwoTone.Warning, + contentDescription = "warning", + modifier = Modifier.padding(start = 8.dp) + ) + } + }, + buttons = { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + TextButton( + modifier = Modifier.weight(1f), + onClick = { showDialog = false }, + ) { Text(stringResource(R.string.cancel)) } + Button( + modifier = Modifier.weight(1f), + onClick = { + showDialog = false + onClick() + }, + ) { Text(stringResource(R.string.send)) } + } } - }, - buttons = { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - TextButton( - modifier = Modifier.weight(1f), - onClick = { showDialog = false }, - ) { Text(stringResource(R.string.cancel)) } - Button( - modifier = Modifier.weight(1f), - onClick = { - showDialog = false - onClick() - }, - ) { Text(stringResource(R.string.send)) } - } - } - ) + ) + } Column { Spacer(modifier = Modifier.height(4.dp)) diff --git a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt index 6abe72cd7..1523d0cae 100644 --- a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.model +package com.geeksville.mesh.ui.radioconfig import android.app.Application import android.net.Uri @@ -39,13 +39,13 @@ import com.geeksville.mesh.android.Logging import com.geeksville.mesh.config import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.deviceProfile +import com.geeksville.mesh.model.Node +import com.geeksville.mesh.model.getChannelList +import com.geeksville.mesh.model.getStringResFrom +import com.geeksville.mesh.model.toChannelSet import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.service.MeshService.ConnectionState -import com.geeksville.mesh.ui.AdminRoute -import com.geeksville.mesh.ui.ConfigRoute -import com.geeksville.mesh.ui.ModuleRoute -import com.geeksville.mesh.ui.ResponseState import com.geeksville.mesh.ui.Route import com.geeksville.mesh.util.UiText import com.google.protobuf.MessageLite diff --git a/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ResponseState.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ResponseState.kt new file mode 100644 index 000000000..0640f4807 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/ResponseState.kt @@ -0,0 +1,32 @@ +/* + * 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.ui.radioconfig + +import com.geeksville.mesh.util.UiText + +/** + * Generic sealed class defines each possible state of a response. + */ +sealed class ResponseState { + data object Empty : ResponseState() + data class Loading(var total: Int = 1, var completed: Int = 0) : ResponseState() + data class Success(val result: T) : ResponseState() + data class Error(val error: UiText) : ResponseState() + + fun isWaiting() = this !is Empty +} diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/AmbientLightingConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/AmbientLightingConfigItemList.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/AmbientLightingConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/AmbientLightingConfigItemList.kt index 2a3eed197..407bfc88e 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/AmbientLightingConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/AmbientLightingConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,12 +33,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun AmbientLightingConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/AudioConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/AudioConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/AudioConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/AudioConfigItemList.kt index ac0f417ec..262ddb086 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/AudioConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/AudioConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,13 +33,13 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.AudioConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun AudioConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/BluetoothConfigItemList.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/BluetoothConfigItemList.kt index 662fa5d6a..00dd1a617 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/BluetoothConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -34,12 +34,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ConfigProtos.Config.BluetoothConfig import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun BluetoothConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/CannedMessageConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/CannedMessageConfigItemList.kt index 577be3e4b..988086771 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/CannedMessageConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -36,13 +36,13 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.CannedMessageConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun CannedMessageConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/ChannelSettingsItemList.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/ChannelSettingsItemList.kt index dbf189c5f..3b2fa30d0 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/ChannelSettingsItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.FastOutSlowInEasing @@ -70,12 +70,12 @@ import com.geeksville.mesh.ChannelProtos.ChannelSettings import com.geeksville.mesh.R import com.geeksville.mesh.channelSettings import com.geeksville.mesh.model.Channel -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.dragContainer import com.geeksville.mesh.ui.components.dragDropItemsIndexed import com.geeksville.mesh.ui.components.rememberDragDropState +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @OptIn(ExperimentalMaterialApi::class) @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/DetectionSensorConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DetectionSensorConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/DetectionSensorConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DetectionSensorConfigItemList.kt index 5d6fe423b..fa845d84d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/DetectionSensorConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DetectionSensorConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -36,13 +36,13 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun DetectionSensorConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DeviceConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DeviceConfigItemList.kt index f90c43ebf..0d3c16c40 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DeviceConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -39,12 +39,12 @@ import com.geeksville.mesh.ConfigProtos.Config.DeviceConfig import com.geeksville.mesh.R import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel private val DeviceConfig.Role.stringRes: Int get() = when (this) { diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DisplayConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DisplayConfigItemList.kt index 8fdd542a8..1d97802c5 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/DisplayConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -34,12 +34,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun DisplayConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/EditChannelDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/EditChannelDialog.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/EditChannelDialog.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/EditChannelDialog.kt index 30eb67145..405cd00a1 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/EditChannelDialog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/EditChannelDialog.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/EditDeviceProfileDialog.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/EditDeviceProfileDialog.kt index 93a108276..e8bf571ee 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/EditDeviceProfileDialog.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/ExternalNotificationConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/ExternalNotificationConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/ExternalNotificationConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/ExternalNotificationConfigItemList.kt index abe534106..094d0d139 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/ExternalNotificationConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/ExternalNotificationConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -36,13 +36,13 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.ExternalNotificationConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference import com.geeksville.mesh.ui.components.TextDividerPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun ExternalNotificationConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/LoRaConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/LoRaConfigItemList.kt index 029d5d8d0..17a3279c4 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/LoRaConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -37,7 +37,6 @@ import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig import com.geeksville.mesh.config import com.geeksville.mesh.copy import com.geeksville.mesh.model.Channel -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.model.RegionInfo import com.geeksville.mesh.model.numChannels import com.geeksville.mesh.ui.components.DropDownPreference @@ -46,6 +45,7 @@ import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun LoRaConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/MQTTConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/MQTTConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/MQTTConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/MQTTConfigItemList.kt index 59587adbf..ef5964161 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/MQTTConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/MQTTConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -38,7 +38,6 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.MQTTConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditPasswordPreference import com.geeksville.mesh.ui.components.EditTextPreference @@ -46,6 +45,7 @@ import com.geeksville.mesh.ui.components.PositionPrecisionPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun MQTTConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/NeighborInfoConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/NeighborInfoConfigItemList.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/NeighborInfoConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/NeighborInfoConfigItemList.kt index 5fd11d5e6..5eb8aa889 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/NeighborInfoConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/NeighborInfoConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -35,12 +35,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos import com.geeksville.mesh.R import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun NeighborInfoConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/NetworkConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/NetworkConfigItemList.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/NetworkConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/NetworkConfigItemList.kt index 45c00f168..a8483bc31 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/NetworkConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/NetworkConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.activity.compose.rememberLauncherForActivityResult import androidx.compose.foundation.layout.fillMaxSize @@ -46,7 +46,6 @@ import com.geeksville.mesh.ConfigProtos.Config.NetworkConfig import com.geeksville.mesh.R import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditIPv4Preference import com.geeksville.mesh.ui.components.EditPasswordPreference @@ -55,6 +54,7 @@ import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SimpleAlertDialog import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/PacketResponseStateDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PacketResponseStateDialog.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/PacketResponseStateDialog.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PacketResponseStateDialog.kt index 32ed25077..0ea426889 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/PacketResponseStateDialog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PacketResponseStateDialog.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Arrangement @@ -37,7 +37,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.geeksville.mesh.R -import com.geeksville.mesh.ui.ResponseState +import com.geeksville.mesh.ui.radioconfig.ResponseState @Composable fun PacketResponseStateDialog( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/PaxcounterConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PaxcounterConfigItemList.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/PaxcounterConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PaxcounterConfigItemList.kt index d1b199045..cc9311947 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/PaxcounterConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PaxcounterConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,12 +33,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun PaxcounterConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PositionConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PositionConfigItemList.kt index 523b637f2..af534c778 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PositionConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -36,13 +36,13 @@ import com.geeksville.mesh.ConfigProtos.Config.PositionConfig import com.geeksville.mesh.Position import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.BitwisePreference import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun PositionConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/PowerConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PowerConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/PowerConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PowerConfigItemList.kt index 471b76d77..5244e1850 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/PowerConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/PowerConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -34,11 +34,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ConfigProtos.Config.PowerConfig import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun PowerConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/RangeTestConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/RangeTestConfigItemList.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/RangeTestConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/RangeTestConfigItemList.kt index d956cf4fa..f77e41665 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/RangeTestConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/RangeTestConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,12 +33,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.RangeTestConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun RangeTestConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/RemoteHardwareConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/RemoteHardwareConfigItemList.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/RemoteHardwareConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/RemoteHardwareConfigItemList.kt index 88c48a72b..adea2af30 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/RemoteHardwareConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/RemoteHardwareConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,12 +33,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.RemoteHardwareConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditListPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun RemoteHardwareConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/SecurityConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/SecurityConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/SecurityConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/SecurityConfigItemList.kt index 4e08db93d..55d7b0550 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/SecurityConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/SecurityConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -34,12 +34,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ConfigProtos.Config.SecurityConfig import com.geeksville.mesh.config import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.ui.components.EditBase64Preference import com.geeksville.mesh.ui.components.EditListPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun SecurityConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/SerialConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/SerialConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/SerialConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/SerialConfigItemList.kt index 0c89cff0e..38d388303 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/SerialConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/SerialConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,13 +33,13 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.SerialConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.DropDownPreference import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun SerialConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/StoreForwardConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/StoreForwardConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/StoreForwardConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/StoreForwardConfigItemList.kt index 42319a85f..90ddf141a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/StoreForwardConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/StoreForwardConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,12 +33,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.StoreForwardConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun StoreForwardConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/TelemetryConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/TelemetryConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/TelemetryConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/TelemetryConfigItemList.kt index fdda8b588..a8e72a3f1 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/TelemetryConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/TelemetryConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -33,12 +33,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.TelemetryConfig import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel @Composable fun TelemetryConfigScreen( diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/UserConfigItemList.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt rename to app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/UserConfigItemList.kt index 87d4321a9..b71bb3c14 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/components/UserConfigItemList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.components.config +package com.geeksville.mesh.ui.radioconfig.components import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -36,13 +36,13 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.copy -import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.model.getInitials import com.geeksville.mesh.ui.components.EditTextPreference import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.RegularPreference import com.geeksville.mesh.ui.components.SwitchPreference +import com.geeksville.mesh.ui.radioconfig.RadioConfigViewModel import com.geeksville.mesh.user @Composable diff --git a/config/detekt/detekt-baseline.xml b/config/detekt/detekt-baseline.xml index a1b8943b3..c13ab3d07 100644 --- a/config/detekt/detekt-baseline.xml +++ b/config/detekt/detekt-baseline.xml @@ -129,7 +129,6 @@ FinalNewline:SoftwareUpdateService.kt$com.geeksville.mesh.service.SoftwareUpdateService.kt FinalNewline:SqlTileWriterExt.kt$com.geeksville.mesh.util.SqlTileWriterExt.kt FinalNewline:TCPInterfaceFactory.kt$com.geeksville.mesh.repository.radio.TCPInterfaceFactory.kt - FinalNewline:Theme.kt$com.geeksville.mesh.ui.theme.Theme.kt FinalNewline:UsbBroadcastReceiver.kt$com.geeksville.mesh.repository.usb.UsbBroadcastReceiver.kt FinalNewline:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt ForbiddenComment:MapFragment.kt$// TODO: Accept filename input param from user @@ -161,7 +160,6 @@ LongMethod:MainActivity.kt$MainActivity$override fun onOptionsItemSelected(item: MenuItem): Boolean LongMethod:MapFragment.kt$@Composable fun MapView( model: UIViewModel = viewModel(), ) LongMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) - LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigItemList( networkConfig: NetworkConfig, enabled: Boolean, onSaveClicked: (NetworkConfig) -> Unit, ) LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigItemList( powerConfig: PowerConfig, enabled: Boolean, onSaveClicked: (PowerConfig) -> Unit, ) LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket) LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigItemList( serialConfig: SerialConfig, enabled: Boolean, onSaveClicked: (SerialConfig) -> Unit, ) @@ -300,20 +298,6 @@ MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$360.0 MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$4 MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$5 - MagicNumber:NavGraph.kt$ConfigRoute.BLUETOOTH$6 - MagicNumber:NavGraph.kt$ConfigRoute.DISPLAY$4 - MagicNumber:NavGraph.kt$ConfigRoute.LORA$5 - MagicNumber:NavGraph.kt$ConfigRoute.NETWORK$3 - MagicNumber:NavGraph.kt$ModuleRoute.AMBIENT_LIGHTING$10 - MagicNumber:NavGraph.kt$ModuleRoute.AUDIO$7 - MagicNumber:NavGraph.kt$ModuleRoute.CANNED_MESSAGE$6 - MagicNumber:NavGraph.kt$ModuleRoute.DETECTION_SENSOR$11 - MagicNumber:NavGraph.kt$ModuleRoute.NEIGHBOR_INFO$9 - MagicNumber:NavGraph.kt$ModuleRoute.PAXCOUNTER$12 - MagicNumber:NavGraph.kt$ModuleRoute.RANGE_TEST$4 - MagicNumber:NavGraph.kt$ModuleRoute.REMOTE_HARDWARE$8 - MagicNumber:NavGraph.kt$ModuleRoute.STORE_FORWARD$3 - MagicNumber:NavGraph.kt$ModuleRoute.TELEMETRY$5 MagicNumber:NodeInfo.kt$DeviceMetrics.Companion$1000 MagicNumber:NodeInfo.kt$EnvironmentMetrics.Companion$1000 MagicNumber:NodeInfo.kt$NodeInfo$0.114 @@ -513,8 +497,6 @@ MultiLineIfElse:NOAAWmsTileSource.kt$NOAAWmsTileSource$sb.append("service=WMS") MultiLineIfElse:NodeInfo.kt$MeshUser$hwModel.name.replace('_', '-').replace('p', '.').lowercase() MultiLineIfElse:NodeInfo.kt$MeshUser$null - MultiLineIfElse:RadioConfigScreen.kt$AlertDialog( onDismissRequest = {}, shape = RoundedCornerShape(16.dp), backgroundColor = MaterialTheme.colors.background, title = { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, ) { Icon( imageVector = Icons.TwoTone.Warning, contentDescription = "warning", modifier = Modifier.padding(end = 8.dp) ) Text( text = "${stringResource(title)}?\n") Icon( imageVector = Icons.TwoTone.Warning, contentDescription = "warning", modifier = Modifier.padding(start = 8.dp) ) } }, buttons = { Row( modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { TextButton( modifier = Modifier.weight(1f), onClick = { showDialog = false }, ) { Text(stringResource(R.string.cancel)) } Button( modifier = Modifier.weight(1f), onClick = { showDialog = false onClick() }, ) { Text(stringResource(R.string.send)) } } } ) - MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$try { setChannels(channelUrl) } catch (ex: Exception) { errormsg("DeviceProfile channel import error", ex) setResponseStateError(ex.customMessage) } MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$viewModelScope.launch { radioConfigRepository.replaceAllSettings(new) } MultiLineIfElse:RadioInterfaceService.kt$RadioInterfaceService$startInterface() MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$cb @@ -582,7 +564,6 @@ NewLineAtEndOfFile:SoftwareUpdateService.kt$com.geeksville.mesh.service.SoftwareUpdateService.kt NewLineAtEndOfFile:SqlTileWriterExt.kt$com.geeksville.mesh.util.SqlTileWriterExt.kt NewLineAtEndOfFile:TCPInterfaceFactory.kt$com.geeksville.mesh.repository.radio.TCPInterfaceFactory.kt - NewLineAtEndOfFile:Theme.kt$com.geeksville.mesh.ui.theme.Theme.kt NewLineAtEndOfFile:UsbBroadcastReceiver.kt$com.geeksville.mesh.repository.usb.UsbBroadcastReceiver.kt NewLineAtEndOfFile:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt NoBlankLineBeforeRbrace:BluetoothInterface.kt$BluetoothInterface$ @@ -617,8 +598,6 @@ NoWildcardImports:BluetoothInterface.kt$import com.geeksville.mesh.service.* NoWildcardImports:DeviceVersionTest.kt$import org.junit.Assert.* NoWildcardImports:ExampleUnitTest.kt$import org.junit.Assert.* - NoWildcardImports:MeshService.kt$import com.geeksville.mesh.* - NoWildcardImports:MeshService.kt$import com.geeksville.mesh.util.* NoWildcardImports:MockInterface.kt$import com.geeksville.mesh.* NoWildcardImports:PreferenceFooter.kt$import androidx.compose.foundation.layout.* NoWildcardImports:PreferenceFooter.kt$import androidx.compose.material.* @@ -732,8 +711,6 @@ WildcardImport:BluetoothInterface.kt$import com.geeksville.mesh.service.* WildcardImport:DeviceVersionTest.kt$import org.junit.Assert.* WildcardImport:ExampleUnitTest.kt$import org.junit.Assert.* - WildcardImport:MeshService.kt$import com.geeksville.mesh.* - WildcardImport:MeshService.kt$import com.geeksville.mesh.util.* WildcardImport:MockInterface.kt$import com.geeksville.mesh.* WildcardImport:PreferenceFooter.kt$import androidx.compose.foundation.layout.* WildcardImport:PreferenceFooter.kt$import androidx.compose.material.*