mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
fix: fix animation stalls and update dependencies for stability (#4784)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
90844301e8
commit
427c0f3bbb
38 changed files with 384 additions and 243 deletions
|
|
@ -30,10 +30,8 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.animateFloatingActionButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
|
|
@ -42,7 +40,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
|
@ -68,7 +65,6 @@ import org.meshtastic.feature.node.component.NodeFilterTextField
|
|||
import org.meshtastic.feature.node.component.NodeItem
|
||||
import org.meshtastic.proto.SharedContact
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
fun NodeListScreen(
|
||||
|
|
@ -125,21 +121,18 @@ fun NodeListScreen(
|
|||
floatingActionButton = {
|
||||
val shareCapable = ourNode?.capabilities?.supportsQrCodeSharing ?: false
|
||||
val sharedContact: SharedContact? by viewModel.sharedContactRequested.collectAsStateWithLifecycle(null)
|
||||
MeshtasticImportFAB(
|
||||
sharedContact = sharedContact,
|
||||
modifier =
|
||||
Modifier.animateFloatingActionButton(
|
||||
visible = !isScrollInProgress && connectionState == ConnectionState.Connected && shareCapable,
|
||||
alignment = Alignment.BottomEnd,
|
||||
),
|
||||
onImport = { uriString ->
|
||||
viewModel.handleScannedUri(uriString) {
|
||||
scope.launch { context.showToast(Res.string.channel_invalid) }
|
||||
}
|
||||
},
|
||||
onDismissSharedContact = { viewModel.setSharedContactRequested(null) },
|
||||
isContactContext = true,
|
||||
)
|
||||
if (!isScrollInProgress && connectionState == ConnectionState.Connected && shareCapable) {
|
||||
MeshtasticImportFAB(
|
||||
sharedContact = sharedContact,
|
||||
onImport = { uriString ->
|
||||
viewModel.handleScannedUri(uriString) {
|
||||
scope.launch { context.showToast(Res.string.channel_invalid) }
|
||||
}
|
||||
},
|
||||
onDismissSharedContact = { viewModel.setSharedContactRequested(null) },
|
||||
isContactContext = true,
|
||||
)
|
||||
}
|
||||
},
|
||||
) { contentPadding ->
|
||||
Box(modifier = Modifier.fillMaxSize().padding(contentPadding).focusable()) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,11 @@ import org.meshtastic.core.resources.air_utilization
|
|||
import org.meshtastic.core.resources.battery
|
||||
import org.meshtastic.core.resources.ch_util_definition
|
||||
import org.meshtastic.core.resources.channel_utilization
|
||||
import org.meshtastic.core.resources.device_metrics_label_value
|
||||
import org.meshtastic.core.resources.device_metrics_log
|
||||
import org.meshtastic.core.resources.device_metrics_numeric_value
|
||||
import org.meshtastic.core.resources.device_metrics_percent_value
|
||||
import org.meshtastic.core.resources.device_metrics_voltage_value
|
||||
import org.meshtastic.core.resources.uptime
|
||||
import org.meshtastic.core.resources.voltage
|
||||
import org.meshtastic.core.ui.component.MaterialBatteryInfo
|
||||
|
|
@ -240,16 +244,23 @@ private fun DeviceMetricsChart(
|
|||
val voltageColor = Device.VOLTAGE.color
|
||||
val chUtilColor = Device.CH_UTIL.color
|
||||
val airUtilColor = Device.AIR_UTIL.color
|
||||
val batteryLabel = stringResource(Res.string.battery)
|
||||
val voltageLabel = stringResource(Res.string.voltage)
|
||||
val channelUtilizationLabel = stringResource(Res.string.channel_utilization)
|
||||
val airUtilizationLabel = stringResource(Res.string.air_utilization)
|
||||
val percentValueTemplate = stringResource(Res.string.device_metrics_percent_value)
|
||||
val voltageValueTemplate = stringResource(Res.string.device_metrics_voltage_value)
|
||||
val numericValueTemplate = stringResource(Res.string.device_metrics_numeric_value)
|
||||
val marker =
|
||||
ChartStyling.rememberMarker(
|
||||
valueFormatter =
|
||||
ChartStyling.createColoredMarkerValueFormatter { value, color ->
|
||||
when (color.copy(alpha = 1f)) {
|
||||
batteryColor -> "Battery: %.1f%%".format(value)
|
||||
voltageColor -> "Voltage: %.1f V".format(value)
|
||||
chUtilColor -> "ChUtil: %.1f%%".format(value)
|
||||
airUtilColor -> "AirUtil: %.1f%%".format(value)
|
||||
else -> "%.1f".format(value)
|
||||
batteryColor -> percentValueTemplate.format(batteryLabel, value)
|
||||
voltageColor -> voltageValueTemplate.format(voltageLabel, value)
|
||||
chUtilColor -> percentValueTemplate.format(channelUtilizationLabel, value)
|
||||
airUtilColor -> percentValueTemplate.format(airUtilizationLabel, value)
|
||||
else -> numericValueTemplate.format(value)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
@ -422,6 +433,11 @@ private fun DeviceMetricsChartPreview() {
|
|||
private fun DeviceMetricsCard(telemetry: Telemetry, isSelected: Boolean, onClick: () -> Unit) {
|
||||
val deviceMetrics = telemetry.device_metrics
|
||||
val time = telemetry.time.toLong() * MS_PER_SEC
|
||||
val channelUtilizationLabel = stringResource(Res.string.channel_utilization)
|
||||
val airUtilizationLabel = stringResource(Res.string.air_utilization)
|
||||
val uptimeLabel = stringResource(Res.string.uptime)
|
||||
val percentValueTemplate = stringResource(Res.string.device_metrics_percent_value)
|
||||
val labelValueTemplate = stringResource(Res.string.device_metrics_label_value)
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp, vertical = 4.dp).clickable { onClick() },
|
||||
border = if (isSelected) BorderStroke(2.dp, MaterialTheme.colorScheme.primary) else null,
|
||||
|
|
@ -471,7 +487,11 @@ private fun DeviceMetricsCard(telemetry: Telemetry, isSelected: Boolean, onClick
|
|||
MetricIndicator(Device.CH_UTIL.color)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "Ch: %.1f%%".format(deviceMetrics.channel_utilization ?: 0f),
|
||||
text =
|
||||
percentValueTemplate.format(
|
||||
channelUtilizationLabel,
|
||||
deviceMetrics.channel_utilization ?: 0f,
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
@ -481,7 +501,11 @@ private fun DeviceMetricsCard(telemetry: Telemetry, isSelected: Boolean, onClick
|
|||
MetricIndicator(Device.AIR_UTIL.color)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "Air: %.1f%%".format(deviceMetrics.air_util_tx ?: 0f),
|
||||
text =
|
||||
percentValueTemplate.format(
|
||||
airUtilizationLabel,
|
||||
deviceMetrics.air_util_tx ?: 0f,
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
@ -489,9 +513,10 @@ private fun DeviceMetricsCard(telemetry: Telemetry, isSelected: Boolean, onClick
|
|||
}
|
||||
Text(
|
||||
text =
|
||||
stringResource(Res.string.uptime) +
|
||||
": " +
|
||||
labelValueTemplate.format(
|
||||
uptimeLabel,
|
||||
formatUptime(deviceMetrics?.uptime_seconds ?: 0),
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue