refactor(config): extract components from `NavGraph` to screens

pull/1375/head
andrekir 2024-10-31 18:17:46 -03:00 zatwierdzone przez Andre K
rodzic 74ae3fd594
commit 1aa0b138fc
25 zmienionych plików z 724 dodań i 264 usunięć

Wyświetl plik

@ -54,43 +54,38 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.geeksville.mesh.Position
import com.geeksville.mesh.R
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.config
import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.model.Channel
import com.geeksville.mesh.model.MetricsViewModel
import com.geeksville.mesh.model.RadioConfigViewModel
import com.geeksville.mesh.moduleConfig
import com.geeksville.mesh.ui.components.DeviceMetricsScreen
import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen
import com.geeksville.mesh.ui.components.SignalMetricsScreen
import com.geeksville.mesh.ui.components.TracerouteLogScreen
import com.geeksville.mesh.ui.components.config.AmbientLightingConfigItemList
import com.geeksville.mesh.ui.components.config.AudioConfigItemList
import com.geeksville.mesh.ui.components.config.BluetoothConfigItemList
import com.geeksville.mesh.ui.components.config.CannedMessageConfigItemList
import com.geeksville.mesh.ui.components.config.ChannelSettingsItemList
import com.geeksville.mesh.ui.components.config.DetectionSensorConfigItemList
import com.geeksville.mesh.ui.components.config.DeviceConfigItemList
import com.geeksville.mesh.ui.components.config.DisplayConfigItemList
import com.geeksville.mesh.ui.components.config.ExternalNotificationConfigItemList
import com.geeksville.mesh.ui.components.config.LoRaConfigItemList
import com.geeksville.mesh.ui.components.config.MQTTConfigItemList
import com.geeksville.mesh.ui.components.config.NeighborInfoConfigItemList
import com.geeksville.mesh.ui.components.config.NetworkConfigItemList
import com.geeksville.mesh.ui.components.config.PacketResponseStateDialog
import com.geeksville.mesh.ui.components.config.PaxcounterConfigItemList
import com.geeksville.mesh.ui.components.config.PositionConfigItemList
import com.geeksville.mesh.ui.components.config.PowerConfigItemList
import com.geeksville.mesh.ui.components.config.RangeTestConfigItemList
import com.geeksville.mesh.ui.components.config.RemoteHardwareConfigItemList
import com.geeksville.mesh.ui.components.config.SecurityConfigItemList
import com.geeksville.mesh.ui.components.config.SerialConfigItemList
import com.geeksville.mesh.ui.components.config.StoreForwardConfigItemList
import com.geeksville.mesh.ui.components.config.TelemetryConfigItemList
import com.geeksville.mesh.ui.components.config.UserConfigItemList
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.google.accompanist.themeadapter.appcompat.AppCompatTheme
import dagger.hilt.android.AndroidEntryPoint
@ -232,7 +227,7 @@ private fun MeshAppBar(
)
}
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Suppress("LongMethod")
@Composable
fun NavGraph(
node: NodeEntity?,
@ -241,22 +236,6 @@ fun NavGraph(
startDestination: String,
modifier: Modifier = Modifier,
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
onComplete = {
val route = state.route
if (ConfigRoute.entries.any { it.name == route } ||
ModuleRoute.entries.any { it.name == route }) {
navController.navigate(route = route)
viewModel.clearPacketResponse()
}
},
)
}
NavHost(
navController = navController,
startDestination = startDestination,
@ -287,268 +266,76 @@ fun NavGraph(
RadioConfigScreen(
node = node,
viewModel = viewModel,
)
) { navController.navigate(route = it) }
}
composable(ConfigRoute.USER.name) {
UserConfigItemList(
userConfig = state.userConfig,
enabled = state.connected,
onSaveClicked = { userInput ->
viewModel.setOwner(userInput)
}
)
UserConfigScreen(viewModel)
}
composable(ConfigRoute.CHANNELS.name) {
ChannelSettingsItemList(
settingsList = state.channelList,
modemPresetName = Channel(loraConfig = state.radioConfig.lora).name,
enabled = state.connected,
maxChannels = viewModel.maxChannels,
onPositiveClicked = { channelListInput ->
viewModel.updateChannels(channelListInput, state.channelList)
},
)
ChannelConfigScreen(viewModel)
}
composable(ConfigRoute.DEVICE.name) {
DeviceConfigItemList(
deviceConfig = state.radioConfig.device,
enabled = state.connected,
onSaveClicked = { deviceInput ->
val config = config { device = deviceInput }
viewModel.setConfig(config)
}
)
DeviceConfigScreen(viewModel)
}
composable(ConfigRoute.POSITION.name) {
val currentPosition = Position(
latitude = node?.latitude ?: 0.0,
longitude = node?.longitude ?: 0.0,
altitude = node?.position?.altitude ?: 0,
time = 1, // ignore time for fixed_position
)
PositionConfigItemList(
location = currentPosition,
positionConfig = state.radioConfig.position,
enabled = state.connected,
onSaveClicked = { locationInput, positionInput ->
if (positionInput.fixedPosition) {
if (locationInput != currentPosition) {
viewModel.setFixedPosition(locationInput)
}
} else {
if (state.radioConfig.position.fixedPosition) {
// fixed position changed from enabled to disabled
viewModel.removeFixedPosition()
}
}
val config = config { position = positionInput }
viewModel.setConfig(config)
}
)
PositionConfigScreen(viewModel)
}
composable(ConfigRoute.POWER.name) {
PowerConfigItemList(
powerConfig = state.radioConfig.power,
enabled = state.connected,
onSaveClicked = { powerInput ->
val config = config { power = powerInput }
viewModel.setConfig(config)
}
)
PowerConfigScreen(viewModel)
}
composable(ConfigRoute.NETWORK.name) {
NetworkConfigItemList(
networkConfig = state.radioConfig.network,
enabled = state.connected,
onSaveClicked = { networkInput ->
val config = config { network = networkInput }
viewModel.setConfig(config)
}
)
NetworkConfigScreen(viewModel)
}
composable(ConfigRoute.DISPLAY.name) {
DisplayConfigItemList(
displayConfig = state.radioConfig.display,
enabled = state.connected,
onSaveClicked = { displayInput ->
val config = config { display = displayInput }
viewModel.setConfig(config)
}
)
DisplayConfigScreen(viewModel)
}
composable(ConfigRoute.LORA.name) {
LoRaConfigItemList(
loraConfig = state.radioConfig.lora,
primarySettings = state.channelList.getOrNull(0) ?: return@composable,
enabled = state.connected,
onSaveClicked = { loraInput ->
val config = config { lora = loraInput }
viewModel.setConfig(config)
},
hasPaFan = viewModel.hasPaFan,
)
LoRaConfigScreen(viewModel)
}
composable(ConfigRoute.BLUETOOTH.name) {
BluetoothConfigItemList(
bluetoothConfig = state.radioConfig.bluetooth,
enabled = state.connected,
onSaveClicked = { bluetoothInput ->
val config = config { bluetooth = bluetoothInput }
viewModel.setConfig(config)
}
)
BluetoothConfigScreen(viewModel)
}
composable(ConfigRoute.SECURITY.name) {
SecurityConfigItemList(
securityConfig = state.radioConfig.security,
enabled = state.connected,
onConfirm = { securityInput ->
val config = config { security = securityInput }
viewModel.setConfig(config)
}
)
SecurityConfigScreen(viewModel)
}
composable(ModuleRoute.MQTT.name) {
MQTTConfigItemList(
mqttConfig = state.moduleConfig.mqtt,
enabled = state.connected,
onSaveClicked = { mqttInput ->
val config = moduleConfig { mqtt = mqttInput }
viewModel.setModuleConfig(config)
}
)
MQTTConfigScreen(viewModel)
}
composable(ModuleRoute.SERIAL.name) {
SerialConfigItemList(
serialConfig = state.moduleConfig.serial,
enabled = state.connected,
onSaveClicked = { serialInput ->
val config = moduleConfig { serial = serialInput }
viewModel.setModuleConfig(config)
}
)
SerialConfigScreen(viewModel)
}
composable(ModuleRoute.EXTERNAL_NOTIFICATION.name) {
ExternalNotificationConfigItemList(
ringtone = state.ringtone,
extNotificationConfig = state.moduleConfig.externalNotification,
enabled = state.connected,
onSaveClicked = { ringtoneInput, extNotificationInput ->
if (ringtoneInput != state.ringtone) {
viewModel.setRingtone(ringtoneInput)
}
if (extNotificationInput != state.moduleConfig.externalNotification) {
val config = moduleConfig { externalNotification = extNotificationInput }
viewModel.setModuleConfig(config)
}
}
)
ExternalNotificationConfigScreen(viewModel)
}
composable(ModuleRoute.STORE_FORWARD.name) {
StoreForwardConfigItemList(
storeForwardConfig = state.moduleConfig.storeForward,
enabled = state.connected,
onSaveClicked = { storeForwardInput ->
val config = moduleConfig { storeForward = storeForwardInput }
viewModel.setModuleConfig(config)
}
)
StoreForwardConfigScreen(viewModel)
}
composable(ModuleRoute.RANGE_TEST.name) {
RangeTestConfigItemList(
rangeTestConfig = state.moduleConfig.rangeTest,
enabled = state.connected,
onSaveClicked = { rangeTestInput ->
val config = moduleConfig { rangeTest = rangeTestInput }
viewModel.setModuleConfig(config)
}
)
RangeTestConfigScreen(viewModel)
}
composable(ModuleRoute.TELEMETRY.name) {
TelemetryConfigItemList(
telemetryConfig = state.moduleConfig.telemetry,
enabled = state.connected,
onSaveClicked = { telemetryInput ->
val config = moduleConfig { telemetry = telemetryInput }
viewModel.setModuleConfig(config)
}
)
TelemetryConfigScreen(viewModel)
}
composable(ModuleRoute.CANNED_MESSAGE.name) {
CannedMessageConfigItemList(
messages = state.cannedMessageMessages,
cannedMessageConfig = state.moduleConfig.cannedMessage,
enabled = state.connected,
onSaveClicked = { messagesInput, cannedMessageInput ->
if (messagesInput != state.cannedMessageMessages) {
viewModel.setCannedMessages(messagesInput)
}
if (cannedMessageInput != state.moduleConfig.cannedMessage) {
val config = moduleConfig { cannedMessage = cannedMessageInput }
viewModel.setModuleConfig(config)
}
}
)
CannedMessageConfigScreen(viewModel)
}
composable(ModuleRoute.AUDIO.name) {
AudioConfigItemList(
audioConfig = state.moduleConfig.audio,
enabled = state.connected,
onSaveClicked = { audioInput ->
val config = moduleConfig { audio = audioInput }
viewModel.setModuleConfig(config)
}
)
AudioConfigScreen(viewModel)
}
composable(ModuleRoute.REMOTE_HARDWARE.name) {
RemoteHardwareConfigItemList(
remoteHardwareConfig = state.moduleConfig.remoteHardware,
enabled = state.connected,
onSaveClicked = { remoteHardwareInput ->
val config = moduleConfig { remoteHardware = remoteHardwareInput }
viewModel.setModuleConfig(config)
}
)
RemoteHardwareConfigScreen(viewModel)
}
composable(ModuleRoute.NEIGHBOR_INFO.name) {
NeighborInfoConfigItemList(
neighborInfoConfig = state.moduleConfig.neighborInfo,
enabled = state.connected,
onSaveClicked = { neighborInfoInput ->
val config = moduleConfig { neighborInfo = neighborInfoInput }
viewModel.setModuleConfig(config)
}
)
NeighborInfoConfigScreen(viewModel)
}
composable(ModuleRoute.AMBIENT_LIGHTING.name) {
AmbientLightingConfigItemList(
ambientLightingConfig = state.moduleConfig.ambientLighting,
enabled = state.connected,
onSaveClicked = { ambientLightingInput ->
val config = moduleConfig { ambientLighting = ambientLightingInput }
viewModel.setModuleConfig(config)
}
)
AmbientLightingConfigScreen(viewModel)
}
composable(ModuleRoute.DETECTION_SENSOR.name) {
DetectionSensorConfigItemList(
detectionSensorConfig = state.moduleConfig.detectionSensor,
enabled = state.connected,
onSaveClicked = { detectionSensorInput ->
val config = moduleConfig { detectionSensor = detectionSensorInput }
viewModel.setModuleConfig(config)
}
)
DetectionSensorConfigScreen(viewModel)
}
composable(ModuleRoute.PAXCOUNTER.name) {
PaxcounterConfigItemList(
paxcounterConfig = state.moduleConfig.paxcounter,
enabled = state.connected,
onSaveClicked = { paxcounterConfigInput ->
val config = moduleConfig { paxcounter = paxcounterConfigInput }
viewModel.setModuleConfig(config)
}
)
PaxcounterConfigScreen(viewModel)
}
}
}

Wyświetl plik

@ -44,6 +44,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile
import com.geeksville.mesh.R
@ -51,17 +52,38 @@ import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.model.RadioConfigViewModel
import com.geeksville.mesh.ui.components.PreferenceCategory
import com.geeksville.mesh.ui.components.config.EditDeviceProfileDialog
import com.geeksville.mesh.ui.components.config.PacketResponseStateDialog
@Suppress("LongMethod")
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
fun RadioConfigScreen(
node: NodeEntity?,
viewModel: RadioConfigViewModel,
viewModel: RadioConfigViewModel = hiltViewModel(),
modifier: Modifier = Modifier,
onNavigate: (String) -> Unit = {}
) {
val isLocal = node?.num == viewModel.myNodeNum
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
val isWaiting = state.responseState.isWaiting()
var isWaiting by remember { mutableStateOf(false) }
if (isWaiting) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = {
isWaiting = false
viewModel.clearPacketResponse()
},
onComplete = {
val route = state.route
if (ConfigRoute.entries.any { it.name == route } ||
ModuleRoute.entries.any { it.name == route }) {
isWaiting = false
viewModel.clearPacketResponse()
onNavigate(route)
}
},
)
}
var deviceProfile by remember { mutableStateOf<DeviceProfile?>(null) }
var showEditDeviceProfileDialog by remember { mutableStateOf(false) }
@ -115,6 +137,7 @@ fun RadioConfigScreen(
isLocal = isLocal,
modifier = modifier,
onRouteClick = { route ->
isWaiting = true
viewModel.setResponseStateLoading(route)
},
onImport = {

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun AmbientLightingConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
AmbientLightingConfigItemList(
ambientLightingConfig = state.moduleConfig.ambientLighting,
enabled = state.connected,
onSaveClicked = { ambientLightingInput ->
val config = moduleConfig { ambientLighting = ambientLightingInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun AmbientLightingConfigItemList(
ambientLightingConfig: ModuleConfigProtos.ModuleConfig.AmbientLightingConfig,

Wyświetl plik

@ -12,14 +12,41 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun AudioConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
AudioConfigItemList(
audioConfig = state.moduleConfig.audio,
enabled = state.connected,
onSaveClicked = { audioInput ->
val config = moduleConfig { audio = audioInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun AudioConfigItemList(
audioConfig: AudioConfig,

Wyświetl plik

@ -12,14 +12,41 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
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
@Composable
fun BluetoothConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
BluetoothConfigItemList(
bluetoothConfig = state.radioConfig.bluetooth,
enabled = state.connected,
onSaveClicked = { bluetoothInput ->
val config = config { bluetooth = bluetoothInput }
viewModel.setConfig(config)
}
)
}
@Composable
fun BluetoothConfigItemList(
bluetoothConfig: BluetoothConfig,

Wyświetl plik

@ -15,14 +15,47 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun CannedMessageConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
CannedMessageConfigItemList(
messages = state.cannedMessageMessages,
cannedMessageConfig = state.moduleConfig.cannedMessage,
enabled = state.connected,
onSaveClicked = { messagesInput, cannedMessageInput ->
if (messagesInput != state.cannedMessageMessages) {
viewModel.setCannedMessages(messagesInput)
}
if (cannedMessageInput != state.moduleConfig.cannedMessage) {
val config = moduleConfig { cannedMessage = cannedMessageInput }
viewModel.setModuleConfig(config)
}
}
)
}
@Composable
fun CannedMessageConfigItemList(
messages: String,

Wyświetl plik

@ -47,10 +47,13 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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
@ -147,6 +150,30 @@ fun ChannelSelection(
)
}
@Composable
fun ChannelConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
ChannelSettingsItemList(
settingsList = state.channelList,
modemPresetName = Channel(loraConfig = state.radioConfig.lora).name,
enabled = state.connected,
maxChannels = viewModel.maxChannels,
onPositiveClicked = { channelListInput ->
viewModel.updateChannels(channelListInput, state.channelList)
},
)
}
@Composable
fun ChannelSettingsItemList(
settingsList: List<ChannelSettings>,

Wyświetl plik

@ -15,14 +15,41 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun DetectionSensorConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
DetectionSensorConfigItemList(
detectionSensorConfig = state.moduleConfig.detectionSensor,
enabled = state.connected,
onSaveClicked = { detectionSensorInput ->
val config = moduleConfig { detectionSensor = detectionSensorInput }
viewModel.setModuleConfig(config)
}
)
}
@Suppress("LongMethod")
@Composable
fun DetectionSensorConfigItemList(

Wyświetl plik

@ -16,9 +16,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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
@ -41,6 +45,29 @@ private val DeviceConfig.Role.stringRes: Int
else -> R.string.unrecognized
}
@Composable
fun DeviceConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
DeviceConfigItemList(
deviceConfig = state.radioConfig.device,
enabled = state.connected,
onSaveClicked = { deviceInput ->
val config = config { device = deviceInput }
viewModel.setConfig(config)
}
)
}
@Composable
fun DeviceConfigItemList(
deviceConfig: DeviceConfig,

Wyświetl plik

@ -12,14 +12,41 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
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
@Composable
fun DisplayConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
DisplayConfigItemList(
displayConfig = state.radioConfig.display,
enabled = state.connected,
onSaveClicked = { displayInput ->
val config = config { display = displayInput }
viewModel.setConfig(config)
}
)
}
@Composable
fun DisplayConfigItemList(
displayConfig: DisplayConfig,

Wyświetl plik

@ -15,14 +15,47 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun ExternalNotificationConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
ExternalNotificationConfigItemList(
ringtone = state.ringtone,
extNotificationConfig = state.moduleConfig.externalNotification,
enabled = state.connected,
onSaveClicked = { ringtoneInput, extNotificationInput ->
if (ringtoneInput != state.ringtone) {
viewModel.setRingtone(ringtoneInput)
}
if (extNotificationInput != state.moduleConfig.externalNotification) {
val config = moduleConfig { externalNotification = extNotificationInput }
viewModel.setModuleConfig(config)
}
}
)
}
@Composable
fun ExternalNotificationConfigItemList(
ringtone: String,

Wyświetl plik

@ -13,10 +13,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.ChannelProtos.ChannelSettings
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
@ -26,6 +30,31 @@ import com.geeksville.mesh.ui.components.PreferenceCategory
import com.geeksville.mesh.ui.components.PreferenceFooter
import com.geeksville.mesh.ui.components.SwitchPreference
@Composable
fun LoRaConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
LoRaConfigItemList(
loraConfig = state.radioConfig.lora,
primarySettings = state.channelList.getOrNull(0) ?: return,
enabled = state.connected,
onSaveClicked = { loraInput ->
val config = config { lora = loraInput }
viewModel.setConfig(config)
},
hasPaFan = viewModel.hasPaFan,
)
}
@Suppress("LongMethod")
@Composable
fun LoRaConfigItemList(

Wyświetl plik

@ -17,8 +17,12 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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
import com.geeksville.mesh.ui.components.PositionPrecisionPreference
@ -26,6 +30,29 @@ import com.geeksville.mesh.ui.components.PreferenceCategory
import com.geeksville.mesh.ui.components.PreferenceFooter
import com.geeksville.mesh.ui.components.SwitchPreference
@Composable
fun MQTTConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
MQTTConfigItemList(
mqttConfig = state.moduleConfig.mqtt,
enabled = state.connected,
onSaveClicked = { mqttInput ->
val config = moduleConfig { mqtt = mqttInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun MQTTConfigItemList(
mqttConfig: MQTTConfig,

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun NeighborInfoConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
NeighborInfoConfigItemList(
neighborInfoConfig = state.moduleConfig.neighborInfo,
enabled = state.connected,
onSaveClicked = { neighborInfoInput ->
val config = moduleConfig { neighborInfo = neighborInfoInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun NeighborInfoConfigItemList(
neighborInfoConfig: ModuleConfigProtos.ModuleConfig.NeighborInfoConfig,

Wyświetl plik

@ -23,9 +23,13 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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
@ -46,6 +50,29 @@ private fun ScanErrorDialog(
onDismiss = onDismiss,
)
@Composable
fun NetworkConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
NetworkConfigItemList(
networkConfig = state.radioConfig.network,
enabled = state.connected,
onSaveClicked = { networkInput ->
val config = config { network = networkInput }
viewModel.setConfig(config)
}
)
}
@Composable
fun NetworkConfigItemList(
networkConfig: NetworkConfig,

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun PaxcounterConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
PaxcounterConfigItemList(
paxcounterConfig = state.moduleConfig.paxcounter,
enabled = state.connected,
onSaveClicked = { paxcounterConfigInput ->
val config = moduleConfig { paxcounter = paxcounterConfigInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun PaxcounterConfigItemList(
paxcounterConfig: ModuleConfigProtos.ModuleConfig.PaxcounterConfig,

Wyświetl plik

@ -12,10 +12,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.ConfigProtos
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
@ -23,6 +27,48 @@ import com.geeksville.mesh.ui.components.PreferenceCategory
import com.geeksville.mesh.ui.components.PreferenceFooter
import com.geeksville.mesh.ui.components.SwitchPreference
@Composable
fun PositionConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
val node by viewModel.destNode.collectAsStateWithLifecycle()
val currentPosition = Position(
latitude = node?.latitude ?: 0.0,
longitude = node?.longitude ?: 0.0,
altitude = node?.position?.altitude ?: 0,
time = 1, // ignore time for fixed_position
)
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
PositionConfigItemList(
location = currentPosition,
positionConfig = state.radioConfig.position,
enabled = state.connected,
onSaveClicked = { locationInput, positionInput ->
if (positionInput.fixedPosition) {
if (locationInput != currentPosition) {
viewModel.setFixedPosition(locationInput)
}
} else {
if (state.radioConfig.position.fixedPosition) {
// fixed position changed from enabled to disabled
viewModel.removeFixedPosition()
}
}
val config = config { position = positionInput }
viewModel.setConfig(config)
}
)
}
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
fun PositionConfigItemList(

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
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
@Composable
fun PowerConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
PowerConfigItemList(
powerConfig = state.radioConfig.power,
enabled = state.connected,
onSaveClicked = { powerInput ->
val config = config { power = powerInput }
viewModel.setConfig(config)
}
)
}
@Composable
fun PowerConfigItemList(
powerConfig: PowerConfig,

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun RangeTestConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
RangeTestConfigItemList(
rangeTestConfig = state.moduleConfig.rangeTest,
enabled = state.connected,
onSaveClicked = { rangeTestInput ->
val config = moduleConfig { rangeTest = rangeTestInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun RangeTestConfigItemList(
rangeTestConfig: RangeTestConfig,

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun RemoteHardwareConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
RemoteHardwareConfigItemList(
remoteHardwareConfig = state.moduleConfig.remoteHardware,
enabled = state.connected,
onSaveClicked = { remoteHardwareInput ->
val config = moduleConfig { remoteHardware = remoteHardwareInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun RemoteHardwareConfigItemList(
remoteHardwareConfig: RemoteHardwareConfig,

Wyświetl plik

@ -12,14 +12,41 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
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
@Composable
fun SecurityConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
SecurityConfigItemList(
securityConfig = state.radioConfig.security,
enabled = state.connected,
onConfirm = { securityInput ->
val config = config { security = securityInput }
viewModel.setConfig(config)
}
)
}
@Suppress("LongMethod")
@Composable
fun SecurityConfigItemList(

Wyświetl plik

@ -12,14 +12,41 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun SerialConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
SerialConfigItemList(
serialConfig = state.moduleConfig.serial,
enabled = state.connected,
onSaveClicked = { serialInput ->
val config = moduleConfig { serial = serialInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun SerialConfigItemList(
serialConfig: SerialConfig,

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun StoreForwardConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
StoreForwardConfigItemList(
storeForwardConfig = state.moduleConfig.storeForward,
enabled = state.connected,
onSaveClicked = { storeForwardInput ->
val config = moduleConfig { storeForward = storeForwardInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun StoreForwardConfigItemList(
storeForwardConfig: StoreForwardConfig,

Wyświetl plik

@ -12,13 +12,40 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
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
@Composable
fun TelemetryConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
TelemetryConfigItemList(
telemetryConfig = state.moduleConfig.telemetry,
enabled = state.connected,
onSaveClicked = { telemetryInput ->
val config = moduleConfig { telemetry = telemetryInput }
viewModel.setModuleConfig(config)
}
)
}
@Composable
fun TelemetryConfigItemList(
telemetryConfig: TelemetryConfig,

Wyświetl plik

@ -15,8 +15,11 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
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
@ -25,6 +28,26 @@ import com.geeksville.mesh.ui.components.RegularPreference
import com.geeksville.mesh.ui.components.SwitchPreference
import com.geeksville.mesh.user
@Composable
fun UserConfigScreen(
viewModel: RadioConfigViewModel = hiltViewModel(),
) {
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
if (state.responseState.isWaiting()) {
PacketResponseStateDialog(
state = state.responseState,
onDismiss = viewModel::clearPacketResponse,
)
}
UserConfigItemList(
userConfig = state.userConfig,
enabled = true,
onSaveClicked = viewModel::setOwner,
)
}
@Composable
fun UserConfigItemList(
userConfig: MeshProtos.User,