diff --git a/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt b/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt index ace833c1d..2071a9e1a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt @@ -59,6 +59,18 @@ fun LinkedCoordinates( } } +@Composable +@Preview +fun LinkedCoordinatesSimplePreview() { + AppTheme { + LinkedCoordinates( + position = Position(37.7749, -122.4194, 0), + format = 1, + nodeName = "Test Node Name" + ) + } +} + @Composable @Preview(showBackground = true) @Preview(showBackground = true, uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES) diff --git a/app/src/main/java/com/geeksville/mesh/ui/SignalInfo.kt b/app/src/main/java/com/geeksville/mesh/ui/SignalInfo.kt new file mode 100644 index 000000000..c092a3dd6 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/SignalInfo.kt @@ -0,0 +1,79 @@ +package com.geeksville.mesh.ui + +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import com.geeksville.mesh.NodeInfo +import com.geeksville.mesh.ui.preview.NodeInfoPreviewParameterProvider +import com.geeksville.mesh.ui.theme.AppTheme + +@Composable +fun SignalInfo( + nodeInfo: NodeInfo, + isThisNode: Boolean +) { + val text = if (isThisNode) { + "ChUtil %.1f%% AirUtilTX %.1f%%".format( + nodeInfo.deviceMetrics?.channelUtilization, + nodeInfo.deviceMetrics?.airUtilTx + ) + } else { + buildString { + if (nodeInfo.channel > 0) append("ch:${nodeInfo.channel}") + if (nodeInfo.snr < 100F && nodeInfo.rssi < 0) { + if (isNotEmpty()) append(" ") + append("RSSI: %d SNR: %.1f".format(nodeInfo.rssi, nodeInfo.snr)) + } + } + } + if (text.isNotEmpty()) { + Text( + text = text, + color = MaterialTheme.colors.onSurface, + fontSize = MaterialTheme.typography.button.fontSize + ) + } +} + +@Composable +@Preview(showBackground = true) +fun SignalInfoSimplePreview() { + AppTheme { + SignalInfo(NodeInfo( + num = 1, + position = null, + lastHeard = 0, + channel = 0, + snr = 12.5F, + rssi = -42, + deviceMetrics = null, + user = null + ), false) + } +} + +@Composable +@Preview(showBackground = true) +@Preview(showBackground = true, uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES) +fun SignalInfoPreview( + @PreviewParameter(NodeInfoPreviewParameterProvider::class) + nodeInfo: NodeInfo +) { + AppTheme { + SignalInfo(nodeInfo, false) + } +} + +@Composable +@Preview(showBackground = true) +@Preview(showBackground = true, uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES) +fun SignalInfoSelfPreview( + @PreviewParameter(NodeInfoPreviewParameterProvider::class) + nodeInfo: NodeInfo +) { + AppTheme { + SignalInfo(nodeInfo, true) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt index a573d2afa..e5d768bfc 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt @@ -54,12 +54,12 @@ class UsersFragment : ScreenFragment("Users"), Logging { val chipNode = itemView.chipNode val nodeNameView = itemView.nodeNameView val distanceView = itemView.distanceView - val signalView = itemView.signalView val envMetrics = itemView.envMetrics val background = itemView.nodeCard val nodePosition = itemView.nodePosition val batteryInfo = itemView.batteryInfo val lastHeard = itemView.lastHeardInfo + val signalInfo = itemView.signalInfo fun blink() { val bg = background.backgroundTintList @@ -83,26 +83,28 @@ class UsersFragment : ScreenFragment("Users"), Logging { } fun bind( - batteryLevel: Int?, - voltage: Float?, - position: Position?, + nodeInfo: NodeInfo, + isThisNode: Boolean, gpsFormat: Int, - nodeName: String?, - lastHeard: Int ) { batteryInfo.setContent { AppTheme { - BatteryInfo(batteryLevel, voltage) + BatteryInfo(nodeInfo.batteryLevel, nodeInfo.voltage) } } nodePosition.setContent { AppTheme { - LinkedCoordinates(position, gpsFormat, nodeName) + LinkedCoordinates(nodeInfo.position, gpsFormat, nodeInfo.user?.longName) } } this.lastHeard.setContent { AppTheme { - LastHeardInfo(lastHeard) + LastHeardInfo(nodeInfo.lastHeard) + } + } + this.signalInfo.setContent { + AppTheme { + SignalInfo(nodeInfo, isThisNode) } } } @@ -250,23 +252,21 @@ class UsersFragment : ScreenFragment("Users"), Logging { */ override fun onBindViewHolder(holder: ViewHolder, position: Int) { val n = nodes[position] - val user = n.user val (textColor, nodeColor) = n.colors val isIgnored: Boolean = ignoreIncomingList.contains(n.num) - val name = user?.longName + val isThisNode = n.num == nodes[0].num - holder.bind(n.batteryLevel, n.voltage, n.validPosition, gpsFormat, name, n.lastHeard) + holder.bind(n, isThisNode, gpsFormat) - holder.nodeNameView.text = name + holder.nodeNameView.text = n.user?.longName with(holder.chipNode) { - text = (user?.shortName ?: "UNK").strikeIf(isIgnored) + text = (n.user?.shortName ?: "UNK").strikeIf(isIgnored) chipBackgroundColor = ColorStateList.valueOf(nodeColor) setTextColor(textColor) } - val ourNodeInfo = nodes[0] - val distance = ourNodeInfo.distanceStr(n, displayUnits) + val distance = nodes[0].distanceStr(n, displayUnits) if (distance != null) { holder.distanceView.text = distance holder.distanceView.visibility = View.VISIBLE @@ -282,28 +282,6 @@ class UsersFragment : ScreenFragment("Users"), Logging { holder.envMetrics.visibility = View.GONE } - if (n.num == ourNodeInfo.num) { - val text = "ChUtil %.1f%% AirUtilTX %.1f%%".format( - n.deviceMetrics?.channelUtilization, - n.deviceMetrics?.airUtilTx - ) - holder.signalView.text = text - holder.signalView.visibility = View.VISIBLE - } else { - val text = buildString { - if (n.channel > 0) append("ch:${n.channel}") - if (n.snr < 100f && n.rssi < 0) { - if (isNotEmpty()) append(" ") - append("rssi:%d snr:%.1f".format(n.rssi, n.snr)) - } - } - if (text.isNotEmpty()) { - holder.signalView.text = text - holder.signalView.visibility = View.VISIBLE - } else { - holder.signalView.visibility = View.INVISIBLE - } - } holder.chipNode.setOnClickListener { popup(it, position) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/preview/PreviewParameterProviders.kt b/app/src/main/java/com/geeksville/mesh/ui/preview/PreviewParameterProviders.kt new file mode 100644 index 000000000..3e2a029c6 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/preview/PreviewParameterProviders.kt @@ -0,0 +1,27 @@ +package com.geeksville.mesh.ui.preview + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.geeksville.mesh.DeviceMetrics +import com.geeksville.mesh.NodeInfo + + +class NodeInfoPreviewParameterProvider: PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + NodeInfo( + num = 1, + position = null, + lastHeard = 0, + channel = 0, + snr = 12.5F, + rssi = -42, + deviceMetrics = DeviceMetrics( + channelUtilization = 2.4F, + airUtilTx = 3.5F, + batteryLevel = 85, + voltage = 3.7F + ), + user = null + ) + ) +} \ No newline at end of file diff --git a/app/src/main/res/layout/adapter_node_layout.xml b/app/src/main/res/layout/adapter_node_layout.xml index 15c15b4e5..0817f6ff3 100644 --- a/app/src/main/res/layout/adapter_node_layout.xml +++ b/app/src/main/res/layout/adapter_node_layout.xml @@ -63,7 +63,7 @@ app:layout_constraintTop_toBottomOf="@+id/nodeNameView" android:layout_marginStart="8dp" android:layout_marginTop="8dp" - tools:composableName="com.geeksville.mesh.ui.LinkedCoordinatesKt.LinkedCoordinatesPreview" + tools:composableName="com.geeksville.mesh.ui.LinkedCoordinatesKt.LinkedCoordinatesSimplePreview" /> - + +