diff --git a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt index fd028c448..9977d96f8 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt @@ -65,6 +65,7 @@ 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.RadioConfigState import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.service.MeshService.ConnectionState @@ -239,107 +240,31 @@ private fun MeshAppBar( ) } -@Suppress("LongMethod", "CyclomaticComplexMethod") +@Suppress("LongMethod") @Composable fun RadioConfigNavHost( node: NodeEntity?, viewModel: RadioConfigViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), - modifier: Modifier, + modifier: Modifier = Modifier, ) { val connectionState by viewModel.connectionState.collectAsStateWithLifecycle() val connected = connectionState == ConnectionState.CONNECTED && node != null - val isLocal = node?.num == viewModel.myNodeNum - val radioConfigState by viewModel.radioConfigState.collectAsStateWithLifecycle() - val deviceProfile by viewModel.deviceProfile.collectAsStateWithLifecycle() - val isWaiting = radioConfigState.responseState.isWaiting() - var showEditDeviceProfileDialog by remember { mutableStateOf(false) } - - val importConfigLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { - if (it.resultCode == Activity.RESULT_OK) { - showEditDeviceProfileDialog = true - it.data?.data?.let { uri -> viewModel.importProfile(uri) } - } - } - - val exportConfigLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { - if (it.resultCode == Activity.RESULT_OK) { - it.data?.data?.let { uri -> viewModel.exportProfile(uri) } - } - } - - if (showEditDeviceProfileDialog) EditDeviceProfileDialog( - title = if (deviceProfile != null) "Import configuration" else "Export configuration", - deviceProfile = deviceProfile ?: viewModel.currentDeviceProfile, - onConfirm = { - showEditDeviceProfileDialog = false - if (deviceProfile != null) { - viewModel.installProfile(it) - } else { - viewModel.setDeviceProfile(it) - val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { - addCategory(Intent.CATEGORY_OPENABLE) - type = "application/*" - putExtra(Intent.EXTRA_TITLE, "${node!!.num.toUInt()}.cfg") - } - exportConfigLauncher.launch(intent) - } - }, - onDismiss = { - showEditDeviceProfileDialog = false - viewModel.setDeviceProfile(null) - } - ) - - if (isWaiting) PacketResponseStateDialog( - radioConfigState.responseState, - onDismiss = { - showEditDeviceProfileDialog = false - viewModel.clearPacketResponse() - }, - onComplete = { - val route = radioConfigState.route - if (ConfigRoute.entries.any { it.name == route } || - ModuleRoute.entries.any { it.name == route }) { - navController.navigate(route) - viewModel.clearPacketResponse() - } - } - ) - NavHost( navController = navController, startDestination = "home", modifier = modifier, ) { composable("home") { - RadioConfigItemList( - enabled = connected && !isWaiting, - isLocal = isLocal, - onRouteClick = { route -> - viewModel.setResponseStateLoading(route) - }, - onImport = { - viewModel.clearPacketResponse() - viewModel.setDeviceProfile(null) - val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { - addCategory(Intent.CATEGORY_OPENABLE) - type = "application/*" - } - importConfigLauncher.launch(intent) - }, - onExport = { - viewModel.clearPacketResponse() - viewModel.setDeviceProfile(null) - showEditDeviceProfileDialog = true - }, + RadioConfigScreen( + node = node, + connected = connected, + radioConfigState = radioConfigState, + viewModel = viewModel, + onNavigate = { navController.navigate(route = it) }, ) } composable(ConfigRoute.USER.name) { @@ -606,6 +531,106 @@ fun RadioConfigNavHost( } } +@Suppress("LongMethod", "CyclomaticComplexMethod") +@Composable +fun RadioConfigScreen( + node: NodeEntity?, + connected: Boolean, + radioConfigState: RadioConfigState, + viewModel: RadioConfigViewModel, + modifier: Modifier = Modifier, + onNavigate: (String) -> Unit = {}, +) { + val isLocal = node?.num == viewModel.myNodeNum + val isWaiting = radioConfigState.responseState.isWaiting() + + val deviceProfile by viewModel.deviceProfile.collectAsStateWithLifecycle() + var showEditDeviceProfileDialog by remember { mutableStateOf(false) } + + val importConfigLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + showEditDeviceProfileDialog = true + it.data?.data?.let { uri -> viewModel.importProfile(uri) } + } + } + + val exportConfigLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) { + it.data?.data?.let { uri -> viewModel.exportProfile(uri) } + } + } + + if (showEditDeviceProfileDialog) { + EditDeviceProfileDialog( + title = if (deviceProfile != null) "Import configuration" else "Export configuration", + deviceProfile = deviceProfile ?: viewModel.currentDeviceProfile, + onConfirm = { + showEditDeviceProfileDialog = false + if (deviceProfile != null) { + viewModel.installProfile(it) + } else { + viewModel.setDeviceProfile(it) + val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "application/*" + putExtra(Intent.EXTRA_TITLE, "${node!!.num.toUInt()}.cfg") + } + exportConfigLauncher.launch(intent) + } + }, + onDismiss = { + showEditDeviceProfileDialog = false + viewModel.setDeviceProfile(null) + } + ) + } + + if (isWaiting) { + PacketResponseStateDialog( + state = radioConfigState.responseState, + onDismiss = { + showEditDeviceProfileDialog = false + viewModel.clearPacketResponse() + }, + onComplete = { + val route = radioConfigState.route + if (ConfigRoute.entries.any { it.name == route } || + ModuleRoute.entries.any { it.name == route }) { + onNavigate(route) + viewModel.clearPacketResponse() + } + }, + ) + } + + RadioConfigItemList( + enabled = connected && !isWaiting, + isLocal = isLocal, + modifier = modifier, + onRouteClick = { route -> + viewModel.setResponseStateLoading(route) + }, + onImport = { + viewModel.clearPacketResponse() + viewModel.setDeviceProfile(null) + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "application/*" + } + importConfigLauncher.launch(intent) + }, + onExport = { + viewModel.clearPacketResponse() + viewModel.setDeviceProfile(null) + showEditDeviceProfileDialog = true + }, + ) +} + @Composable private fun NavCard( title: String,