From 315950b7c68c23b28c1d5af2ffa71e646bedeae5 Mon Sep 17 00:00:00 2001 From: Phil Oliver <3497406+poliver@users.noreply.github.com> Date: Mon, 3 Nov 2025 14:43:02 -0500 Subject: [PATCH] Modularize remaining nodes code (#3599) --- app/detekt-baseline.xml | 69 ------------------- .../mesh/navigation/NodesNavigation.kt | 22 +++--- .../main/java/com/geeksville/mesh/ui/Main.kt | 2 +- core/proto/build.gradle.kts | 1 + .../core/proto}/HardwareModelExtensions.kt | 2 +- feature/node/build.gradle.kts | 4 ++ feature/node/detekt-baseline.xml | 69 +++++++++++++++++++ .../feature/node/detail}/NodeDetailList.kt | 2 +- .../feature/node/detail}/NodeDetailScreen.kt | 5 +- .../feature/node/list}/NodeListScreen.kt | 3 +- .../feature/node}/metrics/CommonCharts.kt | 9 ++- .../feature/node}/metrics/DeviceMetrics.kt | 14 ++-- .../node}/metrics/EnvironmentCharts.kt | 8 +-- .../node}/metrics/EnvironmentMetrics.kt | 7 +- .../node/metrics}/EnvironmentMetricsState.kt | 2 +- .../feature/node/metrics}/GraphUtil.kt | 2 +- .../feature/node}/metrics/HostMetricsLog.kt | 5 +- .../feature/node/metrics}/MetricsViewModel.kt | 10 +-- .../feature/node}/metrics/PaxMetrics.kt | 3 +- .../feature/node}/metrics/PositionLog.kt | 3 +- .../feature/node}/metrics/PowerMetrics.kt | 10 ++- .../feature/node}/metrics/SignalMetrics.kt | 9 ++- .../feature/node}/metrics/TracerouteLog.kt | 5 +- 23 files changed, 125 insertions(+), 141 deletions(-) rename {app/src/main/java/com/geeksville/mesh/util => core/proto/src/main/kotlin/org/meshtastic/core/proto}/HardwareModelExtensions.kt (98%) rename {app/src/main/java/com/geeksville/mesh/ui/node => feature/node/src/main/kotlin/org/meshtastic/feature/node/detail}/NodeDetailList.kt (99%) rename {app/src/main/java/com/geeksville/mesh/ui/node => feature/node/src/main/kotlin/org/meshtastic/feature/node/detail}/NodeDetailScreen.kt (97%) rename {app/src/main/java/com/geeksville/mesh/ui/node => feature/node/src/main/kotlin/org/meshtastic/feature/node/list}/NodeListScreen.kt (99%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/CommonCharts.kt (97%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/DeviceMetrics.kt (97%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/EnvironmentCharts.kt (98%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/EnvironmentMetrics.kt (98%) rename {app/src/main/java/com/geeksville/mesh/model => feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics}/EnvironmentMetricsState.kt (99%) rename {app/src/main/java/com/geeksville/mesh/util => feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics}/GraphUtil.kt (99%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/HostMetricsLog.kt (98%) rename {app/src/main/java/com/geeksville/mesh/model => feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics}/MetricsViewModel.kt (97%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/PaxMetrics.kt (99%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/PositionLog.kt (99%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/PowerMetrics.kt (98%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/SignalMetrics.kt (97%) rename {app/src/main/java/com/geeksville/mesh/ui => feature/node/src/main/kotlin/org/meshtastic/feature/node}/metrics/TracerouteLog.kt (98%) diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml index fb1d6c77d..fae4c81d4 100644 --- a/app/detekt-baseline.xml +++ b/app/detekt-baseline.xml @@ -5,21 +5,11 @@ CommentSpacing:BLEException.kt$BLEConnectionClosing$/// Our interface is being shut down CommentSpacing:Constants.kt$/// a bool true means we expect this condition to continue until, false means device might come back CommentSpacing:Coroutines.kt$/// Wrap launch with an exception handler, FIXME, move into a utility lib - CommentWrapping:SignalMetrics.kt$Metric.SNR$/* Selected 12 as the max to get 4 equal vertical sections. */ ComposableParamOrder:Channel.kt$ChannelScreen ComposableParamOrder:Channel.kt$EditChannelUrl ComposableParamOrder:ConnectionsNavIcon.kt$ConnectionsNavIcon - ComposableParamOrder:DeviceMetrics.kt$DeviceMetricsChart ComposableParamOrder:EmptyStateContent.kt$EmptyStateContent - ComposableParamOrder:EnvironmentCharts.kt$ChartContent - ComposableParamOrder:EnvironmentCharts.kt$EnvironmentMetricsChart - ComposableParamOrder:EnvironmentCharts.kt$MetricPlottingCanvas - ComposableParamOrder:HostMetricsLog.kt$HostMetricsItem - ComposableParamOrder:HostMetricsLog.kt$LogLine - ComposableParamOrder:PaxMetrics.kt$PaxMetricsChart - ComposableParamOrder:PowerMetrics.kt$PowerMetricsChart ComposableParamOrder:Share.kt$ShareScreen - ComposableParamOrder:SignalMetrics.kt$SignalMetricsChart CyclomaticComplexMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) EmptyClassBlock:DebugLogFile.kt$BinaryLogFile${ } EmptyFunctionBlock:NopInterface.kt$NopInterface${ } @@ -45,10 +35,8 @@ FinalNewline:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt ForbiddenComment:SafeBluetooth.kt$SafeBluetooth$// TODO: display some kind of UI about restarting BLE LambdaParameterEventTrailing:Channel.kt$onConfirm - LambdaParameterEventTrailing:TracerouteLog.kt$onNavigateUp LambdaParameterInRestartableEffect:Channel.kt$onConfirm LargeClass:MeshService.kt$MeshService : Service - LongMethod:EnvironmentMetrics.kt$@Composable fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigateUp: () -> Unit) LongMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) MagicNumber:BluetoothInterface.kt$BluetoothInterface$1000 MagicNumber:BluetoothInterface.kt$BluetoothInterface$500 @@ -65,9 +53,6 @@ MagicNumber:MeshService.kt$MeshService$32 MagicNumber:MeshService.kt$MeshService$60000 MagicNumber:MeshService.kt$MeshService$8 - MagicNumber:MetricsViewModel.kt$MetricsViewModel$1000L - MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-5 - MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-7 MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$21972 MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$32809 MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$6790 @@ -91,67 +76,13 @@ ModifierClickableOrder:Channel.kt$clickable(onClick = onClick) ModifierMissing:BLEDevices.kt$BLEDevices ModifierMissing:Channel.kt$ChannelScreen - ModifierMissing:CommonCharts.kt$ChartHeader - ModifierMissing:CommonCharts.kt$Legend - ModifierMissing:CommonCharts.kt$TimeLabels ModifierMissing:Contacts.kt$ContactListView ModifierMissing:Contacts.kt$ContactsScreen ModifierMissing:Contacts.kt$SelectionToolbar - ModifierMissing:DeviceMetrics.kt$DeviceMetricsScreen ModifierMissing:EmptyStateContent.kt$EmptyStateContent - ModifierMissing:EnvironmentMetrics.kt$EnvironmentMetricsScreen - ModifierMissing:HostMetricsLog.kt$HostMetricsLogScreen ModifierMissing:Main.kt$MainScreen ModifierMissing:NetworkDevices.kt$NetworkDevices - ModifierMissing:NodeListScreen.kt$NodeListScreen - ModifierMissing:PaxMetrics.kt$PaxMetricsItem - ModifierMissing:PaxMetrics.kt$PaxMetricsScreen - ModifierMissing:PositionLog.kt$PositionItem - ModifierMissing:PositionLog.kt$PositionLogScreen - ModifierMissing:PowerMetrics.kt$PowerMetricsScreen ModifierMissing:Share.kt$ShareScreen - ModifierMissing:SignalMetrics.kt$SignalMetricsScreen - ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT) - ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.width(dp) - ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier.width(dp) - ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier = modifier.width(dp) - ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier.width(dp) - ModifierNotUsedAtRoot:PaxMetrics.kt$modifier.width(dp) - ModifierNotUsedAtRoot:PowerMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT) - ModifierNotUsedAtRoot:PowerMetrics.kt$modifier = modifier.width(dp) - ModifierNotUsedAtRoot:PowerMetrics.kt$modifier.width(dp) - ModifierNotUsedAtRoot:SignalMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT) - ModifierNotUsedAtRoot:SignalMetrics.kt$modifier = modifier.width(dp) - ModifierNotUsedAtRoot:SignalMetrics.kt$modifier.width(dp) - ModifierNotUsedAtRoot:TracerouteLog.kt$modifier = modifier.fillMaxSize().padding(innerPadding) - ModifierReused:DeviceMetrics.kt$Canvas(modifier = modifier.width(dp)) { val height = size.height val width = size.width for (i in telemetries.indices) { val telemetry = telemetries[i] /* x-value time */ val xRatio = (telemetry.time - oldest.time).toFloat() / timeDiff val x = xRatio * width /* Channel Utilization */ plotPoint( drawContext = drawContext, color = Device.CH_UTIL.color, x = x, value = telemetry.deviceMetrics.channelUtilization, divisor = MAX_PERCENT_VALUE, ) /* Air Utilization Transmit */ plotPoint( drawContext = drawContext, color = Device.AIR_UTIL.color, x = x, value = telemetry.deviceMetrics.airUtilTx, divisor = MAX_PERCENT_VALUE, ) } /* Battery Line */ var index = 0 while (index < telemetries.size) { val path = Path() index = createPath( telemetries = telemetries, index = index, path = path, oldestTime = oldest.time, timeRange = timeDiff, width = width, timeThreshold = selectedTime.timeThreshold(), ) { i -> val telemetry = telemetries.getOrNull(i) ?: telemetries.last() val ratio = telemetry.deviceMetrics.batteryLevel / MAX_PERCENT_VALUE val y = height - (ratio * height) return@createPath y } drawPath( path = path, color = Device.BATTERY.color, style = Stroke(width = GraphUtil.RADIUS, cap = StrokeCap.Round), ) } } - ModifierReused:DeviceMetrics.kt$HorizontalLinesOverlay( modifier.width(dp), lineColors = listOf(graphColor, Color.Yellow, Color.Red, graphColor, graphColor), ) - ModifierReused:DeviceMetrics.kt$TimeAxisOverlay(modifier.width(dp), oldest = oldest.time, newest = newest.time, selectedTime.lineInterval()) - ModifierReused:EnvironmentCharts.kt$Box( contentAlignment = Alignment.TopStart, modifier = modifier.horizontalScroll(state = scrollState, reverseScrolling = true), ) { HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) TimeAxisOverlay(modifier = modifier.width(dp), oldest = oldest, newest = newest, selectedTime.lineInterval()) MetricPlottingCanvas( modifier = modifier.width(dp), telemetries = telemetries, graphData = graphData, selectedTime = selectedTime, oldest = oldest, timeDiff = timeDiff, rightMin = rightMin, rightMax = rightMax, ) } - ModifierReused:EnvironmentCharts.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) - ModifierReused:EnvironmentCharts.kt$MetricPlottingCanvas( modifier = modifier.width(dp), telemetries = telemetries, graphData = graphData, selectedTime = selectedTime, oldest = oldest, timeDiff = timeDiff, rightMin = rightMin, rightMax = rightMax, ) - ModifierReused:EnvironmentCharts.kt$TimeAxisOverlay(modifier = modifier.width(dp), oldest = oldest, newest = newest, selectedTime.lineInterval()) - ModifierReused:PaxMetrics.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { Color.LightGray }) - ModifierReused:PaxMetrics.kt$Row(modifier = modifier.fillMaxWidth().fillMaxHeight(fraction = 0.33f)) { YAxisLabels( modifier = Modifier.weight(Y_AXIS_WEIGHT).fillMaxHeight().padding(start = 8.dp), labelColor = MaterialTheme.colorScheme.onSurface, minValue = minValue, maxValue = maxValue, ) Box( contentAlignment = Alignment.TopStart, modifier = Modifier.horizontalScroll(state = scrollState, reverseScrolling = true).weight(CHART_WEIGHT), ) { HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { Color.LightGray }) TimeAxisOverlay(modifier.width(dp), oldest = minTime, newest = maxTime, timeFrame.lineInterval()) Canvas(modifier = Modifier.width(dp).fillMaxHeight()) { val width = size.width val height = size.height fun xForTime(t: Int): Float = if (maxTime == minTime) width / 2 else (t - minTime).toFloat() / (maxTime - minTime) * width fun yForValue(v: Int): Float = height - (v - minValue) / (maxValue - minValue) * height fun drawLine(series: List<Pair<Int, Int>>, color: Color) { for (i in 1 until series.size) { drawLine( color = color, start = Offset(xForTime(series[i - 1].first), yForValue(series[i - 1].second)), end = Offset(xForTime(series[i].first), yForValue(series[i].second)), strokeWidth = 2.dp.toPx(), ) } } drawLine(bleSeries, PaxSeries.BLE.color) drawLine(wifiSeries, PaxSeries.WIFI.color) drawLine(totalSeries, PaxSeries.PAX.color) } } YAxisLabels( modifier = Modifier.weight(Y_AXIS_WEIGHT).fillMaxHeight().padding(end = 8.dp), labelColor = MaterialTheme.colorScheme.onSurface, minValue = minValue, maxValue = maxValue, ) } - ModifierReused:PaxMetrics.kt$TimeAxisOverlay(modifier.width(dp), oldest = minTime, newest = maxTime, timeFrame.lineInterval()) - ModifierReused:PowerMetrics.kt$Canvas(modifier = modifier.width(dp)) { val width = size.width val height = size.height /* Voltage */ var index = 0 while (index < telemetries.size) { val path = Path() index = createPath( telemetries = telemetries, index = index, path = path, oldestTime = oldest.time, timeRange = timeDiff, width = width, timeThreshold = selectedTime.timeThreshold(), ) { i -> val telemetry = telemetries.getOrNull(i) ?: telemetries.last() val ratio = (retrieveVoltage(selectedChannel, telemetry) - voltageMin) / voltageDiff val y = height - (ratio * height) return@createPath y } drawPath( path = path, color = VOLTAGE_COLOR, style = Stroke(width = GraphUtil.RADIUS, cap = StrokeCap.Round), ) } /* Current */ index = 0 while (index < telemetries.size) { val path = Path() index = createPath( telemetries = telemetries, index = index, path = path, oldestTime = oldest.time, timeRange = timeDiff, width = width, timeThreshold = selectedTime.timeThreshold(), ) { i -> val telemetry = telemetries.getOrNull(i) ?: telemetries.last() val ratio = (retrieveCurrent(selectedChannel, telemetry) - Power.CURRENT.min) / currentDiff val y = height - (ratio * height) return@createPath y } drawPath( path = path, color = Power.CURRENT.color, style = Stroke(width = GraphUtil.RADIUS, cap = StrokeCap.Round), ) } } - ModifierReused:PowerMetrics.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) - ModifierReused:PowerMetrics.kt$TimeAxisOverlay(modifier.width(dp), oldest = oldest.time, newest = newest.time, selectedTime.lineInterval()) - ModifierReused:PowerMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Power.CURRENT.color, minValue = Power.CURRENT.min, maxValue = Power.CURRENT.max, ) - ModifierReused:PowerMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), VOLTAGE_COLOR, minValue = voltageMin, maxValue = voltageMax, ) - ModifierReused:SignalMetrics.kt$Canvas(modifier = modifier.width(dp)) { val width = size.width /* Plot */ for (packet in meshPackets) { val xRatio = (packet.rxTime - oldest.rxTime).toFloat() / timeDiff val x = xRatio * width /* SNR */ plotPoint( drawContext = drawContext, color = Metric.SNR.color, x = x, value = packet.rxSnr - Metric.SNR.min, divisor = snrDiff, ) /* RSSI */ plotPoint( drawContext = drawContext, color = Metric.RSSI.color, x = x, value = packet.rxRssi - Metric.RSSI.min, divisor = rssiDiff, ) } } - ModifierReused:SignalMetrics.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) - ModifierReused:SignalMetrics.kt$TimeAxisOverlay( modifier.width(dp), oldest = oldest.rxTime, newest = newest.rxTime, selectedTime.lineInterval(), ) - ModifierReused:SignalMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Metric.RSSI.color, minValue = Metric.RSSI.min, maxValue = Metric.RSSI.max, ) - ModifierReused:SignalMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Metric.SNR.color, minValue = Metric.SNR.min, maxValue = Metric.SNR.max, ) - ModifierWithoutDefault:CommonCharts.kt$modifier - ModifierWithoutDefault:EnvironmentCharts.kt$modifier - MultipleEmitters:CommonCharts.kt$LegendLabel - MultipleEmitters:DeviceMetrics.kt$DeviceMetricsChart - MultipleEmitters:EnvironmentCharts.kt$EnvironmentMetricsChart - MultipleEmitters:PaxMetrics.kt$PaxMetricsChart - MultipleEmitters:PowerMetrics.kt$PowerMetricsChart - MultipleEmitters:SignalMetrics.kt$SignalMetricsChart MutableStateAutoboxing:Contacts.kt$mutableStateOf(2) NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedAdmin(fromNodeNum: Int, a: AdminProtos.AdminMessage) NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) diff --git a/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt index c646c3388..f6ab5f4fc 100644 --- a/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt +++ b/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt @@ -39,17 +39,6 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import androidx.navigation.navDeepLink -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.DeviceMetricsScreen -import com.geeksville.mesh.ui.metrics.EnvironmentMetricsScreen -import com.geeksville.mesh.ui.metrics.HostMetricsLogScreen -import com.geeksville.mesh.ui.metrics.PaxMetricsScreen -import com.geeksville.mesh.ui.metrics.PositionLogScreen -import com.geeksville.mesh.ui.metrics.PowerMetricsScreen -import com.geeksville.mesh.ui.metrics.SignalMetricsScreen -import com.geeksville.mesh.ui.metrics.TracerouteLogScreen -import com.geeksville.mesh.ui.node.NodeDetailScreen -import com.geeksville.mesh.ui.node.NodeListScreen import org.meshtastic.core.navigation.ContactsRoutes import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI import org.meshtastic.core.navigation.NodeDetailRoutes @@ -58,6 +47,17 @@ import org.meshtastic.core.navigation.Route import org.meshtastic.core.strings.R import org.meshtastic.feature.map.node.NodeMapScreen import org.meshtastic.feature.map.node.NodeMapViewModel +import org.meshtastic.feature.node.detail.NodeDetailScreen +import org.meshtastic.feature.node.list.NodeListScreen +import org.meshtastic.feature.node.metrics.DeviceMetricsScreen +import org.meshtastic.feature.node.metrics.EnvironmentMetricsScreen +import org.meshtastic.feature.node.metrics.HostMetricsLogScreen +import org.meshtastic.feature.node.metrics.MetricsViewModel +import org.meshtastic.feature.node.metrics.PaxMetricsScreen +import org.meshtastic.feature.node.metrics.PositionLogScreen +import org.meshtastic.feature.node.metrics.PowerMetricsScreen +import org.meshtastic.feature.node.metrics.SignalMetricsScreen +import org.meshtastic.feature.node.metrics.TracerouteLogScreen fun NavGraphBuilder.nodesGraph(navController: NavHostController) { navigation(startDestination = NodesRoutes.Nodes) { diff --git a/app/src/main/java/com/geeksville/mesh/ui/Main.kt b/app/src/main/java/com/geeksville/mesh/ui/Main.kt index 7f1a6cacd..856c6d63d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt @@ -94,7 +94,6 @@ import com.geeksville.mesh.repository.radio.MeshActivity import com.geeksville.mesh.service.MeshService import com.geeksville.mesh.ui.connections.DeviceType import com.geeksville.mesh.ui.connections.components.ConnectionsNavIcon -import com.geeksville.mesh.ui.metrics.annotateTraceroute import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.rememberPermissionState @@ -120,6 +119,7 @@ import org.meshtastic.core.ui.qr.ScannedQrCodeDialog import org.meshtastic.core.ui.share.SharedContactDialog import org.meshtastic.core.ui.theme.StatusColors.StatusBlue import org.meshtastic.core.ui.theme.StatusColors.StatusGreen +import org.meshtastic.feature.node.metrics.annotateTraceroute import org.meshtastic.feature.settings.navigation.settingsGraph import org.meshtastic.proto.MeshProtos import timber.log.Timber diff --git a/core/proto/build.gradle.kts b/core/proto/build.gradle.kts index 142880f8f..d7dce83a3 100644 --- a/core/proto/build.gradle.kts +++ b/core/proto/build.gradle.kts @@ -56,6 +56,7 @@ protobuf { dependencies { implementation(projects.core.strings) + implementation(libs.timber) // This needs to be API for consuming modules api(libs.protobuf.kotlin) } diff --git a/app/src/main/java/com/geeksville/mesh/util/HardwareModelExtensions.kt b/core/proto/src/main/kotlin/org/meshtastic/core/proto/HardwareModelExtensions.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/util/HardwareModelExtensions.kt rename to core/proto/src/main/kotlin/org/meshtastic/core/proto/HardwareModelExtensions.kt index 905d76c2e..5aa0ef516 100644 --- a/app/src/main/java/com/geeksville/mesh/util/HardwareModelExtensions.kt +++ b/core/proto/src/main/kotlin/org/meshtastic/core/proto/HardwareModelExtensions.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.util +package org.meshtastic.core.proto import org.meshtastic.proto.MeshProtos import timber.log.Timber diff --git a/feature/node/build.gradle.kts b/feature/node/build.gradle.kts index 837b40dd8..ae51361bc 100644 --- a/feature/node/build.gradle.kts +++ b/feature/node/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { implementation(projects.core.data) implementation(projects.core.database) implementation(projects.core.datastore) + implementation(projects.core.di) implementation(projects.core.model) implementation(projects.core.proto) implementation(projects.core.service) @@ -35,10 +36,13 @@ dependencies { implementation(projects.core.ui) implementation(projects.core.navigation) + implementation(libs.androidx.activity.compose) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.ui.text) implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.hilt.lifecycle.viewmodel.compose) + implementation(libs.androidx.navigation.common) implementation(libs.timber) implementation(libs.coil) implementation(libs.markdown.renderer.android) diff --git a/feature/node/detekt-baseline.xml b/feature/node/detekt-baseline.xml index 2238abd36..d3fc2282a 100644 --- a/feature/node/detekt-baseline.xml +++ b/feature/node/detekt-baseline.xml @@ -2,16 +2,85 @@ + CommentWrapping:SignalMetrics.kt$Metric.SNR$/* Selected 12 as the max to get 4 equal vertical sections. */ + ComposableParamOrder:DeviceMetrics.kt$DeviceMetricsChart ComposableParamOrder:ElevationInfo.kt$ElevationInfo + ComposableParamOrder:EnvironmentCharts.kt$ChartContent + ComposableParamOrder:EnvironmentCharts.kt$EnvironmentMetricsChart + ComposableParamOrder:EnvironmentCharts.kt$MetricPlottingCanvas + ComposableParamOrder:HostMetricsLog.kt$HostMetricsItem + ComposableParamOrder:HostMetricsLog.kt$LogLine ComposableParamOrder:LastHeardInfo.kt$LastHeardInfo ComposableParamOrder:NodeFilterTextField.kt$NodeFilterTextField ComposableParamOrder:NodeItem.kt$NodeItem + ComposableParamOrder:PaxMetrics.kt$PaxMetricsChart + ComposableParamOrder:PowerMetrics.kt$PowerMetricsChart ComposableParamOrder:SatelliteCountInfo.kt$SatelliteCountInfo + ComposableParamOrder:SignalMetrics.kt$SignalMetricsChart ComposableParamOrder:TracerouteButton.kt$TracerouteButton + LambdaParameterEventTrailing:TracerouteLog.kt$onNavigateUp + LongMethod:EnvironmentMetrics.kt$@Composable fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigateUp: () -> Unit) LongMethod:NodeDetailsSection.kt$@Composable private fun MainNodeDetails(node: Node) + MagicNumber:MetricsViewModel.kt$MetricsViewModel$1000L + MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-5 + MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-7 + ModifierMissing:CommonCharts.kt$ChartHeader + ModifierMissing:CommonCharts.kt$Legend + ModifierMissing:CommonCharts.kt$TimeLabels + ModifierMissing:DeviceMetrics.kt$DeviceMetricsScreen + ModifierMissing:EnvironmentMetrics.kt$EnvironmentMetricsScreen + ModifierMissing:HostMetricsLog.kt$HostMetricsLogScreen + ModifierMissing:NodeListScreen.kt$NodeListScreen ModifierMissing:NodeStatusIcons.kt$NodeStatusIcons + ModifierMissing:PaxMetrics.kt$PaxMetricsItem + ModifierMissing:PaxMetrics.kt$PaxMetricsScreen + ModifierMissing:PositionLog.kt$PositionItem + ModifierMissing:PositionLog.kt$PositionLogScreen + ModifierMissing:PowerMetrics.kt$PowerMetricsScreen + ModifierMissing:SignalMetrics.kt$SignalMetricsScreen + ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT) + ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.width(dp) + ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier.width(dp) + ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier = modifier.width(dp) + ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier.width(dp) + ModifierNotUsedAtRoot:PaxMetrics.kt$modifier.width(dp) + ModifierNotUsedAtRoot:PowerMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT) + ModifierNotUsedAtRoot:PowerMetrics.kt$modifier = modifier.width(dp) + ModifierNotUsedAtRoot:PowerMetrics.kt$modifier.width(dp) + ModifierNotUsedAtRoot:SignalMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT) + ModifierNotUsedAtRoot:SignalMetrics.kt$modifier = modifier.width(dp) + ModifierNotUsedAtRoot:SignalMetrics.kt$modifier.width(dp) + ModifierNotUsedAtRoot:TracerouteLog.kt$modifier = modifier.fillMaxSize().padding(innerPadding) + ModifierReused:DeviceMetrics.kt$Canvas(modifier = modifier.width(dp)) { val height = size.height val width = size.width for (i in telemetries.indices) { val telemetry = telemetries[i] /* x-value time */ val xRatio = (telemetry.time - oldest.time).toFloat() / timeDiff val x = xRatio * width /* Channel Utilization */ plotPoint( drawContext = drawContext, color = Device.CH_UTIL.color, x = x, value = telemetry.deviceMetrics.channelUtilization, divisor = MAX_PERCENT_VALUE, ) /* Air Utilization Transmit */ plotPoint( drawContext = drawContext, color = Device.AIR_UTIL.color, x = x, value = telemetry.deviceMetrics.airUtilTx, divisor = MAX_PERCENT_VALUE, ) } /* Battery Line */ var index = 0 while (index < telemetries.size) { val path = Path() index = createPath( telemetries = telemetries, index = index, path = path, oldestTime = oldest.time, timeRange = timeDiff, width = width, timeThreshold = selectedTime.timeThreshold(), ) { i -> val telemetry = telemetries.getOrNull(i) ?: telemetries.last() val ratio = telemetry.deviceMetrics.batteryLevel / MAX_PERCENT_VALUE val y = height - (ratio * height) return@createPath y } drawPath( path = path, color = Device.BATTERY.color, style = Stroke(width = GraphUtil.RADIUS, cap = StrokeCap.Round), ) } } + ModifierReused:DeviceMetrics.kt$HorizontalLinesOverlay( modifier.width(dp), lineColors = listOf(graphColor, Color.Yellow, Color.Red, graphColor, graphColor), ) + ModifierReused:DeviceMetrics.kt$TimeAxisOverlay(modifier.width(dp), oldest = oldest.time, newest = newest.time, selectedTime.lineInterval()) + ModifierReused:EnvironmentCharts.kt$Box( contentAlignment = Alignment.TopStart, modifier = modifier.horizontalScroll(state = scrollState, reverseScrolling = true), ) { HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) TimeAxisOverlay(modifier = modifier.width(dp), oldest = oldest, newest = newest, selectedTime.lineInterval()) MetricPlottingCanvas( modifier = modifier.width(dp), telemetries = telemetries, graphData = graphData, selectedTime = selectedTime, oldest = oldest, timeDiff = timeDiff, rightMin = rightMin, rightMax = rightMax, ) } + ModifierReused:EnvironmentCharts.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) + ModifierReused:EnvironmentCharts.kt$MetricPlottingCanvas( modifier = modifier.width(dp), telemetries = telemetries, graphData = graphData, selectedTime = selectedTime, oldest = oldest, timeDiff = timeDiff, rightMin = rightMin, rightMax = rightMax, ) + ModifierReused:EnvironmentCharts.kt$TimeAxisOverlay(modifier = modifier.width(dp), oldest = oldest, newest = newest, selectedTime.lineInterval()) + ModifierReused:PaxMetrics.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { Color.LightGray }) + ModifierReused:PaxMetrics.kt$Row(modifier = modifier.fillMaxWidth().fillMaxHeight(fraction = 0.33f)) { YAxisLabels( modifier = Modifier.weight(Y_AXIS_WEIGHT).fillMaxHeight().padding(start = 8.dp), labelColor = MaterialTheme.colorScheme.onSurface, minValue = minValue, maxValue = maxValue, ) Box( contentAlignment = Alignment.TopStart, modifier = Modifier.horizontalScroll(state = scrollState, reverseScrolling = true).weight(CHART_WEIGHT), ) { HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { Color.LightGray }) TimeAxisOverlay(modifier.width(dp), oldest = minTime, newest = maxTime, timeFrame.lineInterval()) Canvas(modifier = Modifier.width(dp).fillMaxHeight()) { val width = size.width val height = size.height fun xForTime(t: Int): Float = if (maxTime == minTime) width / 2 else (t - minTime).toFloat() / (maxTime - minTime) * width fun yForValue(v: Int): Float = height - (v - minValue) / (maxValue - minValue) * height fun drawLine(series: List<Pair<Int, Int>>, color: Color) { for (i in 1 until series.size) { drawLine( color = color, start = Offset(xForTime(series[i - 1].first), yForValue(series[i - 1].second)), end = Offset(xForTime(series[i].first), yForValue(series[i].second)), strokeWidth = 2.dp.toPx(), ) } } drawLine(bleSeries, PaxSeries.BLE.color) drawLine(wifiSeries, PaxSeries.WIFI.color) drawLine(totalSeries, PaxSeries.PAX.color) } } YAxisLabels( modifier = Modifier.weight(Y_AXIS_WEIGHT).fillMaxHeight().padding(end = 8.dp), labelColor = MaterialTheme.colorScheme.onSurface, minValue = minValue, maxValue = maxValue, ) } + ModifierReused:PaxMetrics.kt$TimeAxisOverlay(modifier.width(dp), oldest = minTime, newest = maxTime, timeFrame.lineInterval()) + ModifierReused:PowerMetrics.kt$Canvas(modifier = modifier.width(dp)) { val width = size.width val height = size.height /* Voltage */ var index = 0 while (index < telemetries.size) { val path = Path() index = createPath( telemetries = telemetries, index = index, path = path, oldestTime = oldest.time, timeRange = timeDiff, width = width, timeThreshold = selectedTime.timeThreshold(), ) { i -> val telemetry = telemetries.getOrNull(i) ?: telemetries.last() val ratio = (retrieveVoltage(selectedChannel, telemetry) - voltageMin) / voltageDiff val y = height - (ratio * height) return@createPath y } drawPath( path = path, color = VOLTAGE_COLOR, style = Stroke(width = GraphUtil.RADIUS, cap = StrokeCap.Round), ) } /* Current */ index = 0 while (index < telemetries.size) { val path = Path() index = createPath( telemetries = telemetries, index = index, path = path, oldestTime = oldest.time, timeRange = timeDiff, width = width, timeThreshold = selectedTime.timeThreshold(), ) { i -> val telemetry = telemetries.getOrNull(i) ?: telemetries.last() val ratio = (retrieveCurrent(selectedChannel, telemetry) - Power.CURRENT.min) / currentDiff val y = height - (ratio * height) return@createPath y } drawPath( path = path, color = Power.CURRENT.color, style = Stroke(width = GraphUtil.RADIUS, cap = StrokeCap.Round), ) } } + ModifierReused:PowerMetrics.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) + ModifierReused:PowerMetrics.kt$TimeAxisOverlay(modifier.width(dp), oldest = oldest.time, newest = newest.time, selectedTime.lineInterval()) + ModifierReused:PowerMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Power.CURRENT.color, minValue = Power.CURRENT.min, maxValue = Power.CURRENT.max, ) + ModifierReused:PowerMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), VOLTAGE_COLOR, minValue = voltageMin, maxValue = voltageMax, ) + ModifierReused:SignalMetrics.kt$Canvas(modifier = modifier.width(dp)) { val width = size.width /* Plot */ for (packet in meshPackets) { val xRatio = (packet.rxTime - oldest.rxTime).toFloat() / timeDiff val x = xRatio * width /* SNR */ plotPoint( drawContext = drawContext, color = Metric.SNR.color, x = x, value = packet.rxSnr - Metric.SNR.min, divisor = snrDiff, ) /* RSSI */ plotPoint( drawContext = drawContext, color = Metric.RSSI.color, x = x, value = packet.rxRssi - Metric.RSSI.min, divisor = rssiDiff, ) } } + ModifierReused:SignalMetrics.kt$HorizontalLinesOverlay(modifier.width(dp), lineColors = List(size = 5) { graphColor }) + ModifierReused:SignalMetrics.kt$TimeAxisOverlay( modifier.width(dp), oldest = oldest.rxTime, newest = newest.rxTime, selectedTime.lineInterval(), ) + ModifierReused:SignalMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Metric.RSSI.color, minValue = Metric.RSSI.min, maxValue = Metric.RSSI.max, ) + ModifierReused:SignalMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Metric.SNR.color, minValue = Metric.SNR.min, maxValue = Metric.SNR.max, ) + ModifierWithoutDefault:CommonCharts.kt$modifier + ModifierWithoutDefault:EnvironmentCharts.kt$modifier + MultipleEmitters:CommonCharts.kt$LegendLabel + MultipleEmitters:DeviceMetrics.kt$DeviceMetricsChart + MultipleEmitters:EnvironmentCharts.kt$EnvironmentMetricsChart MultipleEmitters:NodeDetailsSection.kt$MainNodeDetails + MultipleEmitters:PaxMetrics.kt$PaxMetricsChart + MultipleEmitters:PowerMetrics.kt$PowerMetricsChart MultipleEmitters:RemoteDeviceActions.kt$RemoteDeviceActions + MultipleEmitters:SignalMetrics.kt$SignalMetricsChart ParameterNaming:NodeFilterTextField.kt$onToggleShowIgnored PreviewPublic:NodeItem.kt$NodeInfoPreview PreviewPublic:NodeItem.kt$NodeInfoSimplePreview diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailList.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailList.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailList.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailList.kt index f16ac8c35..8ad94eebf 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailList.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailList.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.node +package org.meshtastic.feature.node.detail import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt index 8225f4c71..19bda743c 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.node +package org.meshtastic.feature.node.detail import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize @@ -30,13 +30,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket import org.meshtastic.core.navigation.Route import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.feature.node.component.NodeMenuAction -import org.meshtastic.feature.node.detail.NodeDetailViewModel +import org.meshtastic.feature.node.metrics.MetricsViewModel import org.meshtastic.feature.node.model.LogsType import org.meshtastic.feature.node.model.NodeDetailAction diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/NodeListScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/node/NodeListScreen.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt index 56b4647f9..3a92600ab 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/NodeListScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.node +package org.meshtastic.feature.node.list import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background @@ -69,7 +69,6 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusRed import org.meshtastic.feature.node.component.NodeActionDialogs import org.meshtastic.feature.node.component.NodeFilterTextField import org.meshtastic.feature.node.component.NodeItem -import org.meshtastic.feature.node.list.NodeListViewModel import org.meshtastic.proto.AdminProtos @OptIn(ExperimentalMaterial3ExpressiveApi::class) diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/CommonCharts.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/CommonCharts.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt index 46faaddac..96748275c 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/CommonCharts.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import android.graphics.Paint import android.graphics.Typeface @@ -56,11 +56,10 @@ import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.geeksville.mesh.model.Environment -import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_MINUTE_FORMAT -import com.geeksville.mesh.ui.metrics.CommonCharts.MAX_PERCENT_VALUE -import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC import org.meshtastic.core.strings.R +import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_MINUTE_FORMAT +import org.meshtastic.feature.node.metrics.CommonCharts.MAX_PERCENT_VALUE +import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC import java.text.DateFormat object CommonCharts { diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/DeviceMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/DeviceMetrics.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt index ecd4bf65d..fee492ef9 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/DeviceMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.Canvas import androidx.compose.foundation.horizontalScroll @@ -60,13 +60,6 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT -import com.geeksville.mesh.ui.metrics.CommonCharts.MAX_PERCENT_VALUE -import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC -import com.geeksville.mesh.util.GraphUtil -import com.geeksville.mesh.util.GraphUtil.createPath -import com.geeksville.mesh.util.GraphUtil.plotPoint import org.meshtastic.core.strings.R import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.MaterialBatteryInfo @@ -76,6 +69,11 @@ import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.GraphColors.Cyan import org.meshtastic.core.ui.theme.GraphColors.Green import org.meshtastic.core.ui.theme.GraphColors.Magenta +import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_FORMAT +import org.meshtastic.feature.node.metrics.CommonCharts.MAX_PERCENT_VALUE +import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC +import org.meshtastic.feature.node.metrics.GraphUtil.createPath +import org.meshtastic.feature.node.metrics.GraphUtil.plotPoint import org.meshtastic.feature.node.model.TimeFrame import org.meshtastic.proto.TelemetryProtos import org.meshtastic.proto.TelemetryProtos.Telemetry diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentCharts.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentCharts.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt index cc29a935a..619d184c9 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentCharts.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.Canvas import androidx.compose.foundation.ScrollState @@ -40,11 +40,9 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalWindowInfo import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.geeksville.mesh.model.Environment -import com.geeksville.mesh.model.EnvironmentGraphingData -import com.geeksville.mesh.util.GraphUtil.createPath -import com.geeksville.mesh.util.GraphUtil.drawPathWithGradient import org.meshtastic.core.strings.R +import org.meshtastic.feature.node.metrics.GraphUtil.createPath +import org.meshtastic.feature.node.metrics.GraphUtil.drawPathWithGradient import org.meshtastic.feature.node.model.TimeFrame import org.meshtastic.proto.TelemetryProtos.Telemetry diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt index 183241ca0..58df5a4e0 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -49,9 +49,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT -import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit import org.meshtastic.core.strings.R import org.meshtastic.core.ui.component.IaqDisplayMode @@ -59,6 +56,8 @@ import org.meshtastic.core.ui.component.IndoorAirQuality import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.OptionLabel import org.meshtastic.core.ui.component.SlidingSelector +import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_FORMAT +import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC import org.meshtastic.feature.node.model.TimeFrame import org.meshtastic.proto.TelemetryProtos import org.meshtastic.proto.TelemetryProtos.Telemetry diff --git a/app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetricsState.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetricsState.kt index 3de99782c..e7bc8c897 100644 --- a/app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetricsState.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.model +package org.meshtastic.feature.node.metrics import androidx.compose.ui.graphics.Color import org.meshtastic.core.model.util.UnitConversions diff --git a/app/src/main/java/com/geeksville/mesh/util/GraphUtil.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/GraphUtil.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/util/GraphUtil.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/GraphUtil.kt index dd3dcad6b..d195fa238 100644 --- a/app/src/main/java/com/geeksville/mesh/util/GraphUtil.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/GraphUtil.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.util +package org.meshtastic.feature.node.metrics import android.content.res.Resources import androidx.compose.ui.geometry.Offset diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt index 23bd577d3..98dfd9b2f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable @@ -54,12 +54,11 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.strings.R import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.theme.AppTheme +import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_FORMAT import org.meshtastic.proto.TelemetryProtos import java.text.DecimalFormat diff --git a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt index ec8a28c37..7915c5cab 100644 --- a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.model +package org.meshtastic.feature.node.metrics import android.app.Application import android.net.Uri @@ -23,7 +23,6 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.navigation.toRoute -import com.geeksville.mesh.util.safeNumber import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -49,12 +48,11 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.di.CoroutineDispatchers import org.meshtastic.core.model.DataPacket import org.meshtastic.core.navigation.NodesRoutes -import org.meshtastic.core.prefs.map.MapPrefs +import org.meshtastic.core.proto.safeNumber import org.meshtastic.core.proto.toPosition import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.strings.R -import org.meshtastic.feature.map.model.CustomTileSource import org.meshtastic.feature.node.model.MetricsState import org.meshtastic.feature.node.model.TimeFrame import org.meshtastic.proto.MeshProtos @@ -88,7 +86,6 @@ constructor( private val nodeRepository: NodeRepository, private val deviceHardwareRepository: DeviceHardwareRepository, private val firmwareReleaseRepository: FirmwareReleaseRepository, - private val mapPrefs: MapPrefs, ) : ViewModel() { private val destNum = savedStateHandle.toRoute().destNum @@ -116,9 +113,6 @@ constructor( fun getUser(nodeNum: Int) = nodeRepository.getUser(nodeNum) - val tileSource - get() = CustomTileSource.getTileSource(mapPrefs.mapStyle) - fun deleteLog(uuid: String) = viewModelScope.launch(dispatchers.io) { meshLogRepository.deleteLog(uuid) } fun clearPosition() = viewModelScope.launch(dispatchers.io) { diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt index 5b5ab8fce..a19ebbe87 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.Canvas import androidx.compose.foundation.horizontalScroll @@ -54,7 +54,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel import org.meshtastic.core.database.entity.MeshLog import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.strings.R diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/PositionLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt similarity index 99% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/PositionLog.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt index 3ea113823..0d0a875dc 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/PositionLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import android.app.Activity import android.content.Intent @@ -62,7 +62,6 @@ import androidx.compose.ui.tooling.preview.PreviewScreenSizes import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel import org.meshtastic.core.model.util.metersIn import org.meshtastic.core.model.util.toString import org.meshtastic.core.proto.formatPositionTime diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/PowerMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/PowerMetrics.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt index 646f6e17f..171d2cf94 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/PowerMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.annotation.StringRes import androidx.compose.foundation.Canvas @@ -60,17 +60,15 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT -import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC -import com.geeksville.mesh.util.GraphUtil -import com.geeksville.mesh.util.GraphUtil.createPath import org.meshtastic.core.strings.R import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.OptionLabel import org.meshtastic.core.ui.component.SlidingSelector import org.meshtastic.core.ui.theme.GraphColors.InfantryBlue import org.meshtastic.core.ui.theme.GraphColors.Red +import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_FORMAT +import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC +import org.meshtastic.feature.node.metrics.GraphUtil.createPath import org.meshtastic.feature.node.model.TimeFrame import org.meshtastic.proto.TelemetryProtos.Telemetry import kotlin.math.ceil diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/SignalMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/SignalMetrics.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt index bbb04c957..d311b17f1 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/SignalMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.Canvas import androidx.compose.foundation.horizontalScroll @@ -57,16 +57,15 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT -import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC -import com.geeksville.mesh.util.GraphUtil.plotPoint import org.meshtastic.core.strings.R import org.meshtastic.core.ui.component.LoraSignalIndicator import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.OptionLabel import org.meshtastic.core.ui.component.SlidingSelector import org.meshtastic.core.ui.component.SnrAndRssi +import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_FORMAT +import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC +import org.meshtastic.feature.node.metrics.GraphUtil.plotPoint import org.meshtastic.feature.node.model.TimeFrame import org.meshtastic.proto.MeshProtos.MeshPacket diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/TracerouteLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt similarity index 98% rename from app/src/main/java/com/geeksville/mesh/ui/metrics/TracerouteLog.kt rename to feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt index a7d6bfdef..0a68e16ef 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/TracerouteLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.ui.metrics +package org.meshtastic.feature.node.metrics import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable @@ -62,8 +62,6 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.MetricsViewModel -import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC import org.meshtastic.core.model.fullRouteDiscovery import org.meshtastic.core.model.getTracerouteResponse import org.meshtastic.core.strings.R @@ -75,6 +73,7 @@ import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.StatusColors.StatusGreen import org.meshtastic.core.ui.theme.StatusColors.StatusOrange import org.meshtastic.core.ui.theme.StatusColors.StatusYellow +import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC import org.meshtastic.proto.MeshProtos import java.text.DateFormat