kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: move node detail logs to shared ViewModel
rodzic
e7b30597b7
commit
b668a21b68
|
@ -38,6 +38,7 @@ 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
|
||||
|
@ -129,20 +130,11 @@ class NavGraphFragment : ScreenFragment("NavGraph"), Logging {
|
|||
|
||||
AppCompatTheme {
|
||||
val navController: NavHostController = rememberNavController()
|
||||
// Get current back stack entry
|
||||
// val backStackEntry by navController.currentBackStackEntryAsState()
|
||||
// Get the name of the current screen
|
||||
// val currentScreen = backStackEntry?.destination?.route?.let { route ->
|
||||
// NavRoute.entries.find { it.name == route }?.title
|
||||
// }
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
MeshAppBar(
|
||||
currentScreen = node?.user?.longName
|
||||
?: stringResource(R.string.unknown_username),
|
||||
// canNavigateBack = navController.previousBackStackEntry != null,
|
||||
// navigateUp = { navController.navigateUp() },
|
||||
canNavigateBack = true,
|
||||
navigateUp = {
|
||||
if (navController.previousBackStackEntry != null) {
|
||||
|
@ -233,7 +225,7 @@ private fun MeshAppBar(
|
|||
IconButton(onClick = navigateUp) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
null,
|
||||
contentDescription = stringResource(id = R.string.navigate_back),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -256,9 +248,6 @@ fun NavGraph(
|
|||
val radioConfigState by viewModel.radioConfigState.collectAsStateWithLifecycle()
|
||||
val isWaiting = radioConfigState.responseState.isWaiting()
|
||||
|
||||
val metricsViewModel: MetricsViewModel = hiltViewModel()
|
||||
val metricsState by metricsViewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
if (isWaiting) {
|
||||
PacketResponseStateDialog(
|
||||
state = radioConfigState.responseState,
|
||||
|
@ -282,27 +271,25 @@ fun NavGraph(
|
|||
modifier = modifier,
|
||||
) {
|
||||
composable("NodeDetails") {
|
||||
NodeDetailsScreen(
|
||||
NodeDetailScreen(
|
||||
node = node,
|
||||
metricsState = metricsState,
|
||||
onNavigate = { navController.navigate(route = it) },
|
||||
setSelectedNode = metricsViewModel::setSelectedNode,
|
||||
)
|
||||
) { navController.navigate(route = it) }
|
||||
}
|
||||
composable("DeviceMetrics") {
|
||||
DeviceMetricsScreen(metricsState.deviceMetrics)
|
||||
val parentEntry = remember { navController.getBackStackEntry("NodeDetails") }
|
||||
DeviceMetricsScreen(hiltViewModel<MetricsViewModel>(parentEntry))
|
||||
}
|
||||
composable("EnvironmentMetrics") {
|
||||
EnvironmentMetricsScreen(
|
||||
metricsState.environmentMetrics,
|
||||
metricsState.environmentDisplayFahrenheit,
|
||||
)
|
||||
}
|
||||
composable("TracerouteList") {
|
||||
TracerouteLogScreen(metricsViewModel)
|
||||
val parentEntry = remember { navController.getBackStackEntry("NodeDetails") }
|
||||
EnvironmentMetricsScreen(hiltViewModel<MetricsViewModel>(parentEntry))
|
||||
}
|
||||
composable("SignalMetrics") {
|
||||
SignalMetricsScreen(metricsState.signalMetrics)
|
||||
val parentEntry = remember { navController.getBackStackEntry("NodeDetails") }
|
||||
SignalMetricsScreen(hiltViewModel<MetricsViewModel>(parentEntry))
|
||||
}
|
||||
composable("TracerouteList") {
|
||||
val parentEntry = remember { navController.getBackStackEntry("NodeDetails") }
|
||||
TracerouteLogScreen(hiltViewModel<MetricsViewModel>(parentEntry))
|
||||
}
|
||||
composable("RadioConfig") {
|
||||
RadioConfigScreen(
|
||||
|
|
|
@ -46,6 +46,7 @@ import androidx.compose.material.icons.filled.WaterDrop
|
|||
import androidx.compose.material.icons.filled.Work
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
@ -56,9 +57,12 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.database.entity.NodeEntity
|
||||
import com.geeksville.mesh.model.MetricsState
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import com.geeksville.mesh.ui.components.PreferenceCategory
|
||||
import com.geeksville.mesh.ui.preview.NodeEntityPreviewParameterProvider
|
||||
import com.geeksville.mesh.ui.theme.AppTheme
|
||||
|
@ -67,21 +71,21 @@ import java.util.concurrent.TimeUnit
|
|||
import kotlin.math.ln
|
||||
|
||||
@Composable
|
||||
fun NodeDetailsScreen(
|
||||
fun NodeDetailScreen(
|
||||
node: NodeEntity?,
|
||||
metricsState: MetricsState,
|
||||
viewModel: MetricsViewModel = hiltViewModel(),
|
||||
modifier: Modifier = Modifier,
|
||||
onNavigate: (String) -> Unit,
|
||||
setSelectedNode: (Int) -> Unit,
|
||||
) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
if (node != null) {
|
||||
LaunchedEffect(node.num) {
|
||||
setSelectedNode(node.num)
|
||||
viewModel.setSelectedNode(node.num)
|
||||
}
|
||||
|
||||
NodeDetailsItemList(
|
||||
NodeDetailList(
|
||||
node = node,
|
||||
metricsState = metricsState,
|
||||
metricsState = state,
|
||||
onNavigate = onNavigate,
|
||||
modifier = modifier,
|
||||
)
|
||||
|
@ -97,7 +101,7 @@ fun NodeDetailsScreen(
|
|||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun NodeDetailsItemList(
|
||||
private fun NodeDetailList(
|
||||
node: NodeEntity,
|
||||
metricsState: MetricsState,
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -453,6 +457,6 @@ private fun NodeDetailsPreview(
|
|||
node: NodeEntity
|
||||
) {
|
||||
AppTheme {
|
||||
NodeDetailsItemList(node, MetricsState.Empty)
|
||||
NodeDetailList(node, MetricsState.Empty)
|
||||
}
|
||||
}
|
|
@ -34,8 +34,11 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.TelemetryProtos.Telemetry
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import com.geeksville.mesh.ui.BatteryInfo
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.X_AXIS_SPACING
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.MS_PER_SEC
|
||||
|
@ -56,8 +59,10 @@ private val LEGEND_DATA = listOf(
|
|||
)
|
||||
|
||||
@Composable
|
||||
fun DeviceMetricsScreen(telemetries: List<Telemetry>) {
|
||||
|
||||
fun DeviceMetricsScreen(
|
||||
viewModel: MetricsViewModel = hiltViewModel(),
|
||||
) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
var displayInfoDialog by remember { mutableStateOf(false) }
|
||||
|
||||
Column {
|
||||
|
@ -76,14 +81,14 @@ fun DeviceMetricsScreen(telemetries: List<Telemetry>) {
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight(fraction = 0.33f),
|
||||
telemetries.reversed(),
|
||||
state.deviceMetrics.reversed(),
|
||||
promptInfoDialog = { displayInfoDialog = true }
|
||||
)
|
||||
/* Device Metric Cards */
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
items(telemetries) { telemetry -> DeviceMetricsCard(telemetry) }
|
||||
items(state.deviceMetrics) { telemetry -> DeviceMetricsCard(telemetry) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,12 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.TelemetryProtos.Telemetry
|
||||
import com.geeksville.mesh.copy
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.X_AXIS_SPACING
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.MS_PER_SEC
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.TIME_FORMAT
|
||||
|
@ -69,15 +72,19 @@ private val LEGEND_DATA = listOf(
|
|||
)
|
||||
|
||||
@Composable
|
||||
fun EnvironmentMetricsScreen(telemetries: List<Telemetry>, environmentDisplayFahrenheit: Boolean) {
|
||||
fun EnvironmentMetricsScreen(
|
||||
viewModel: MetricsViewModel = hiltViewModel(),
|
||||
) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
/* Convert Celsius to Fahrenheit */
|
||||
@Suppress("MagicNumber")
|
||||
fun celsiusToFahrenheit(celsius: Float): Float {
|
||||
return (celsius * 1.8F) + 32
|
||||
}
|
||||
|
||||
val processedTelemetries: List<Telemetry> = if (environmentDisplayFahrenheit) {
|
||||
telemetries.map { telemetry ->
|
||||
val processedTelemetries: List<Telemetry> = if (state.environmentDisplayFahrenheit) {
|
||||
state.environmentMetrics.map { telemetry ->
|
||||
val temperatureFahrenheit =
|
||||
celsiusToFahrenheit(telemetry.environmentMetrics.temperature)
|
||||
telemetry.copy {
|
||||
|
@ -86,7 +93,7 @@ fun EnvironmentMetricsScreen(telemetries: List<Telemetry>, environmentDisplayFah
|
|||
}
|
||||
}
|
||||
} else {
|
||||
telemetries
|
||||
state.environmentMetrics
|
||||
}
|
||||
|
||||
var displayInfoDialog by remember { mutableStateOf(false) }
|
||||
|
@ -117,7 +124,7 @@ fun EnvironmentMetricsScreen(telemetries: List<Telemetry>, environmentDisplayFah
|
|||
items(processedTelemetries) { telemetry ->
|
||||
EnvironmentMetricsCard(
|
||||
telemetry,
|
||||
environmentDisplayFahrenheit
|
||||
state.environmentDisplayFahrenheit
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,8 +36,11 @@ import androidx.compose.ui.platform.LocalDensity
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.MeshProtos.MeshPacket
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.MS_PER_SEC
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.LINE_LIMIT
|
||||
import com.geeksville.mesh.ui.components.CommonCharts.TEXT_PAINT_ALPHA
|
||||
|
@ -61,8 +64,10 @@ private val LEGEND_DATA = listOf(
|
|||
)
|
||||
|
||||
@Composable
|
||||
fun SignalMetricsScreen(meshPackets: List<MeshPacket>) {
|
||||
|
||||
fun SignalMetricsScreen(
|
||||
viewModel: MetricsViewModel = hiltViewModel(),
|
||||
) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
var displayInfoDialog by remember { mutableStateOf(false) }
|
||||
|
||||
Column {
|
||||
|
@ -81,14 +86,14 @@ fun SignalMetricsScreen(meshPackets: List<MeshPacket>) {
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight(fraction = 0.33f),
|
||||
meshPackets = meshPackets.reversed(),
|
||||
meshPackets = state.signalMetrics.reversed(),
|
||||
promptInfoDialog = { displayInfoDialog = true }
|
||||
)
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
items(meshPackets) { meshPacket -> SignalMetricsCard(meshPacket) }
|
||||
items(state.signalMetrics) { meshPacket -> SignalMetricsCard(meshPacket) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue