kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor(config): extract screen logic from `NavHost`
rodzic
42f9ef24fd
commit
d10b58073c
|
@ -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,
|
||||
|
|
Ładowanie…
Reference in New Issue