kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: move `RadioConfig` files to separate package
rodzic
7794c08190
commit
ad9a3a5e49
|
@ -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
|
||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Route.RadioConfig> {
|
||||
RadioConfigScreen(
|
||||
onNavigate = navController::navigate,
|
||||
)
|
||||
}
|
||||
composable<Route.User> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
UserConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.ChannelConfig> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
ChannelConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Device> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
DeviceConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Position> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
PositionConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Power> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
PowerConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Network> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
NetworkConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Display> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
DisplayConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.LoRa> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
LoRaConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Bluetooth> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
BluetoothConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Security> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
SecurityConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.MQTT> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
MQTTConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Serial> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
SerialConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.ExtNotification> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
ExternalNotificationConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.StoreForward> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
StoreForwardConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.RangeTest> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
RangeTestConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Telemetry> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
TelemetryConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.CannedMessage> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
CannedMessageConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Audio> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
AudioConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.RemoteHardware> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
RemoteHardwareConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.NeighborInfo> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
NeighborInfoConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.AmbientLighting> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
AmbientLightingConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.DetectionSensor> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
DetectionSensorConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
composable<Route.Paxcounter> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
PaxcounterConfigScreen(
|
||||
viewModel = hiltViewModel<RadioConfigViewModel>(parentEntry),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<ConfigRoute> = 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<ModuleRoute> = 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<out T> {
|
||||
data object Empty : ResponseState<Nothing>()
|
||||
data class Loading(var total: Int = 1, var completed: Int = 0) : ResponseState<Nothing>()
|
||||
data class Success<T>(val result: T) : ResponseState<T>()
|
||||
data class Error(val error: UiText) : ResponseState<Nothing>()
|
||||
|
||||
fun isWaiting() = this !is Empty
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun NavGraph(
|
||||
navController: NavHostController = rememberNavController(),
|
||||
|
@ -320,101 +195,7 @@ fun NavGraph(
|
|||
val parentEntry = remember { navController.getBackStackEntry<Route.NodeDetail>() }
|
||||
TracerouteLogScreen(hiltViewModel<MetricsViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.RadioConfig> {
|
||||
RadioConfigScreen { navController.navigate(route = it) }
|
||||
}
|
||||
composable<Route.User> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
UserConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Channels> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
ChannelConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Device> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
DeviceConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Position> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
PositionConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Power> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
PowerConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Network> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
NetworkConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Display> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
DisplayConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.LoRa> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
LoRaConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Bluetooth> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
BluetoothConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Security> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
SecurityConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.MQTT> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
MQTTConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Serial> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
SerialConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.ExtNotification> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
ExternalNotificationConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.StoreForward> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
StoreForwardConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.RangeTest> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
RangeTestConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Telemetry> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
TelemetryConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.CannedMessage> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
CannedMessageConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Audio> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
AudioConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.RemoteHardware> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
RemoteHardwareConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.NeighborInfo> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
NeighborInfoConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.AmbientLighting> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
AmbientLightingConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.DetectionSensor> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
DetectionSensorConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
composable<Route.Paxcounter> {
|
||||
val parentEntry = remember { navController.getBackStackEntry<Route.RadioConfig>() }
|
||||
PaxcounterConfigScreen(hiltViewModel<RadioConfigViewModel>(parentEntry))
|
||||
}
|
||||
addRadioConfigSection(navController)
|
||||
composable<Route.Share> { backStackEntry ->
|
||||
val message = backStackEntry.toRoute<Route.Share>().message
|
||||
ShareScreen(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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),
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ConfigRoute> = entries.filter {
|
||||
when {
|
||||
metadata == null -> true
|
||||
it == BLUETOOTH -> metadata.hasBluetooth
|
||||
it == NETWORK -> metadata.hasWifi || metadata.hasEthernet
|
||||
else -> true // Include all other routes by default
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ModuleRoute> = entries.filter {
|
||||
when (metadata) {
|
||||
null -> true
|
||||
else -> metadata.excludedModules and it.bitfield == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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))
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<out T> {
|
||||
data object Empty : ResponseState<Nothing>()
|
||||
data class Loading(var total: Int = 1, var completed: Int = 0) : ResponseState<Nothing>()
|
||||
data class Success<T>(val result: T) : ResponseState<T>()
|
||||
data class Error(val error: UiText) : ResponseState<Nothing>()
|
||||
|
||||
fun isWaiting() = this !is Empty
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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) {
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <T> PacketResponseStateDialog(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
|
@ -129,7 +129,6 @@
|
|||
<ID>FinalNewline:SoftwareUpdateService.kt$com.geeksville.mesh.service.SoftwareUpdateService.kt</ID>
|
||||
<ID>FinalNewline:SqlTileWriterExt.kt$com.geeksville.mesh.util.SqlTileWriterExt.kt</ID>
|
||||
<ID>FinalNewline:TCPInterfaceFactory.kt$com.geeksville.mesh.repository.radio.TCPInterfaceFactory.kt</ID>
|
||||
<ID>FinalNewline:Theme.kt$com.geeksville.mesh.ui.theme.Theme.kt</ID>
|
||||
<ID>FinalNewline:UsbBroadcastReceiver.kt$com.geeksville.mesh.repository.usb.UsbBroadcastReceiver.kt</ID>
|
||||
<ID>FinalNewline:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt</ID>
|
||||
<ID>ForbiddenComment:MapFragment.kt$// TODO: Accept filename input param from user</ID>
|
||||
|
@ -161,7 +160,6 @@
|
|||
<ID>LongMethod:MainActivity.kt$MainActivity$override fun onOptionsItemSelected(item: MenuItem): Boolean</ID>
|
||||
<ID>LongMethod:MapFragment.kt$@Composable fun MapView( model: UIViewModel = viewModel(), )</ID>
|
||||
<ID>LongMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)</ID>
|
||||
<ID>LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigItemList( networkConfig: NetworkConfig, enabled: Boolean, onSaveClicked: (NetworkConfig) -> Unit, )</ID>
|
||||
<ID>LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigItemList( powerConfig: PowerConfig, enabled: Boolean, onSaveClicked: (PowerConfig) -> Unit, )</ID>
|
||||
<ID>LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigItemList( serialConfig: SerialConfig, enabled: Boolean, onSaveClicked: (SerialConfig) -> Unit, )</ID>
|
||||
|
@ -300,20 +298,6 @@
|
|||
<ID>MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$360.0</ID>
|
||||
<ID>MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$4</ID>
|
||||
<ID>MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$5</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ConfigRoute.BLUETOOTH$6</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ConfigRoute.DISPLAY$4</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ConfigRoute.LORA$5</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ConfigRoute.NETWORK$3</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.AMBIENT_LIGHTING$10</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.AUDIO$7</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.CANNED_MESSAGE$6</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.DETECTION_SENSOR$11</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.NEIGHBOR_INFO$9</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.PAXCOUNTER$12</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.RANGE_TEST$4</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.REMOTE_HARDWARE$8</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.STORE_FORWARD$3</ID>
|
||||
<ID>MagicNumber:NavGraph.kt$ModuleRoute.TELEMETRY$5</ID>
|
||||
<ID>MagicNumber:NodeInfo.kt$DeviceMetrics.Companion$1000</ID>
|
||||
<ID>MagicNumber:NodeInfo.kt$EnvironmentMetrics.Companion$1000</ID>
|
||||
<ID>MagicNumber:NodeInfo.kt$NodeInfo$0.114</ID>
|
||||
|
@ -513,8 +497,6 @@
|
|||
<ID>MultiLineIfElse:NOAAWmsTileSource.kt$NOAAWmsTileSource$sb.append("service=WMS")</ID>
|
||||
<ID>MultiLineIfElse:NodeInfo.kt$MeshUser$hwModel.name.replace('_', '-').replace('p', '.').lowercase()</ID>
|
||||
<ID>MultiLineIfElse:NodeInfo.kt$MeshUser$null</ID>
|
||||
<ID>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)) } } } )</ID>
|
||||
<ID>MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$try { setChannels(channelUrl) } catch (ex: Exception) { errormsg("DeviceProfile channel import error", ex) setResponseStateError(ex.customMessage) }</ID>
|
||||
<ID>MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$viewModelScope.launch { radioConfigRepository.replaceAllSettings(new) }</ID>
|
||||
<ID>MultiLineIfElse:RadioInterfaceService.kt$RadioInterfaceService$startInterface()</ID>
|
||||
<ID>MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$cb</ID>
|
||||
|
@ -582,7 +564,6 @@
|
|||
<ID>NewLineAtEndOfFile:SoftwareUpdateService.kt$com.geeksville.mesh.service.SoftwareUpdateService.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:SqlTileWriterExt.kt$com.geeksville.mesh.util.SqlTileWriterExt.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:TCPInterfaceFactory.kt$com.geeksville.mesh.repository.radio.TCPInterfaceFactory.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:Theme.kt$com.geeksville.mesh.ui.theme.Theme.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:UsbBroadcastReceiver.kt$com.geeksville.mesh.repository.usb.UsbBroadcastReceiver.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt</ID>
|
||||
<ID>NoBlankLineBeforeRbrace:BluetoothInterface.kt$BluetoothInterface$ </ID>
|
||||
|
@ -617,8 +598,6 @@
|
|||
<ID>NoWildcardImports:BluetoothInterface.kt$import com.geeksville.mesh.service.*</ID>
|
||||
<ID>NoWildcardImports:DeviceVersionTest.kt$import org.junit.Assert.*</ID>
|
||||
<ID>NoWildcardImports:ExampleUnitTest.kt$import org.junit.Assert.*</ID>
|
||||
<ID>NoWildcardImports:MeshService.kt$import com.geeksville.mesh.*</ID>
|
||||
<ID>NoWildcardImports:MeshService.kt$import com.geeksville.mesh.util.*</ID>
|
||||
<ID>NoWildcardImports:MockInterface.kt$import com.geeksville.mesh.*</ID>
|
||||
<ID>NoWildcardImports:PreferenceFooter.kt$import androidx.compose.foundation.layout.*</ID>
|
||||
<ID>NoWildcardImports:PreferenceFooter.kt$import androidx.compose.material.*</ID>
|
||||
|
@ -732,8 +711,6 @@
|
|||
<ID>WildcardImport:BluetoothInterface.kt$import com.geeksville.mesh.service.*</ID>
|
||||
<ID>WildcardImport:DeviceVersionTest.kt$import org.junit.Assert.*</ID>
|
||||
<ID>WildcardImport:ExampleUnitTest.kt$import org.junit.Assert.*</ID>
|
||||
<ID>WildcardImport:MeshService.kt$import com.geeksville.mesh.*</ID>
|
||||
<ID>WildcardImport:MeshService.kt$import com.geeksville.mesh.util.*</ID>
|
||||
<ID>WildcardImport:MockInterface.kt$import com.geeksville.mesh.*</ID>
|
||||
<ID>WildcardImport:PreferenceFooter.kt$import androidx.compose.foundation.layout.*</ID>
|
||||
<ID>WildcardImport:PreferenceFooter.kt$import androidx.compose.material.*</ID>
|
||||
|
|
Ładowanie…
Reference in New Issue