feat: Add contentColor parameter to info components (#3363)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich
2025-10-06 17:02:44 -05:00
committed by GitHub
parent 6a71891790
commit ff9d621978
9 changed files with 76 additions and 52 deletions
@@ -109,7 +109,7 @@ fun SnrAndRssi(snr: Float, rssi: Int) {
/** Displays a human readable description and icon representing the signal quality. */ /** Displays a human readable description and icon representing the signal quality. */
@Composable @Composable
fun LoraSignalIndicator(snr: Float, rssi: Int) { fun LoraSignalIndicator(snr: Float, rssi: Int, contentColor: Color = MaterialTheme.colorScheme.onSurface) {
val quality = determineSignalQuality(snr, rssi) val quality = determineSignalQuality(snr, rssi)
Column( Column(
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
@@ -125,6 +125,7 @@ fun LoraSignalIndicator(snr: Float, rssi: Int) {
Text( Text(
text = "${stringResource(R.string.signal)} ${stringResource(quality.nameRes)}", text = "${stringResource(R.string.signal)} ${stringResource(quality.nameRes)}",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = contentColor,
) )
} }
} }
@@ -32,6 +32,7 @@ import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -51,7 +52,12 @@ private const val SIZE_ICON = 20
@Suppress("MagicNumber", "LongMethod") @Suppress("MagicNumber", "LongMethod")
@Composable @Composable
fun MaterialBatteryInfo(modifier: Modifier = Modifier, level: Int?, voltage: Float? = null) { fun MaterialBatteryInfo(
modifier: Modifier = Modifier,
level: Int?,
voltage: Float? = null,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
) {
val levelString = FORMAT.format(level) val levelString = FORMAT.format(level)
Row( Row(
@@ -63,22 +69,18 @@ fun MaterialBatteryInfo(modifier: Modifier = Modifier, level: Int?, voltage: Flo
Icon( Icon(
modifier = Modifier.size(SIZE_ICON.dp), modifier = Modifier.size(SIZE_ICON.dp),
imageVector = MeshtasticIcons.BatteryUnknown, imageVector = MeshtasticIcons.BatteryUnknown,
tint = MaterialTheme.colorScheme.onSurface, tint = contentColor,
contentDescription = stringResource(R.string.unknown), contentDescription = stringResource(R.string.unknown),
) )
} else if (level > 100) { } else if (level > 100) {
Icon( Icon(
modifier = Modifier.size(SIZE_ICON.dp).rotate(90f), modifier = Modifier.size(SIZE_ICON.dp).rotate(90f),
imageVector = Icons.Rounded.Power, imageVector = Icons.Rounded.Power,
tint = MaterialTheme.colorScheme.onSurface, tint = contentColor,
contentDescription = levelString, contentDescription = levelString,
) )
Text( Text(text = "PWD", color = contentColor, style = MaterialTheme.typography.labelMedium)
text = "PWD",
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.labelMedium,
)
} else { } else {
// Map battery percentage to color // Map battery percentage to color
val fillColor = val fillColor =
@@ -108,24 +110,16 @@ fun MaterialBatteryInfo(modifier: Modifier = Modifier, level: Int?, voltage: Flo
) )
}, },
imageVector = MeshtasticIcons.BatteryEmpty, imageVector = MeshtasticIcons.BatteryEmpty,
tint = MaterialTheme.colorScheme.onSurface, tint = contentColor,
contentDescription = levelString, contentDescription = levelString,
) )
Text( Text(text = levelString, color = contentColor, style = MaterialTheme.typography.labelMedium)
text = levelString,
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.labelMedium,
)
} }
voltage voltage
?.takeIf { it > 0 } ?.takeIf { it > 0 }
?.let { ?.let {
Text( Text(text = "%.2fV".format(it), color = contentColor, style = MaterialTheme.typography.labelMedium)
text = "%.2fV".format(it),
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.labelMedium,
)
} }
} }
} }
@@ -27,6 +27,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
@@ -42,7 +43,12 @@ const val MAX_VALID_RSSI = 0
@Suppress("LongMethod") @Suppress("LongMethod")
@Composable @Composable
fun SignalInfo(modifier: Modifier = Modifier, node: Node, isThisNode: Boolean) { fun SignalInfo(
modifier: Modifier = Modifier,
node: Node,
isThisNode: Boolean,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
) {
val text = val text =
if (isThisNode) { if (isThisNode) {
stringResource(R.string.channel_air_util) stringResource(R.string.channel_air_util)
@@ -72,7 +78,7 @@ fun SignalInfo(modifier: Modifier = Modifier, node: Node, isThisNode: Boolean) {
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
if (text.isNotEmpty()) { if (text.isNotEmpty()) {
Text(text = text, color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.labelSmall) Text(text = text, color = contentColor, style = MaterialTheme.typography.labelSmall)
} }
/* We only know the Signal Quality from direct nodes aka 0 hop. */ /* We only know the Signal Quality from direct nodes aka 0 hop. */
if (node.hopsAway <= 0) { if (node.hopsAway <= 0) {
@@ -98,7 +104,7 @@ fun SignalInfo(modifier: Modifier = Modifier, node: Node, isThisNode: Boolean) {
Text( Text(
text = "${stringResource(R.string.signal)} ${stringResource(quality.nameRes)}", text = "${stringResource(R.string.signal)} ${stringResource(quality.nameRes)}",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurface, color = contentColor,
maxLines = 1, maxLines = 1,
) )
} }
@@ -19,20 +19,27 @@ package org.meshtastic.feature.node.component
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.SocialDistance import androidx.compose.material.icons.rounded.SocialDistance
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import org.meshtastic.core.strings.R import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.AppTheme
@Composable @Composable
fun DistanceInfo(distance: String, modifier: Modifier = Modifier) { fun DistanceInfo(
distance: String,
modifier: Modifier = Modifier,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
) {
IconInfo( IconInfo(
modifier = modifier, modifier = modifier,
icon = Icons.Rounded.SocialDistance, icon = Icons.Rounded.SocialDistance,
contentDescription = stringResource(R.string.distance), contentDescription = stringResource(R.string.distance),
text = distance, text = distance,
contentColor = contentColor,
) )
} }
@@ -20,6 +20,7 @@ package org.meshtastic.feature.node.component
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig.DisplayUnits import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig.DisplayUnits
@@ -35,12 +36,14 @@ fun ElevationInfo(
altitude: Int, altitude: Int,
system: DisplayUnits, system: DisplayUnits,
suffix: String = stringResource(R.string.elevation_suffix), suffix: String = stringResource(R.string.elevation_suffix),
contentColor: Color = MaterialTheme.colorScheme.onSurface,
) { ) {
IconInfo( IconInfo(
modifier = modifier, modifier = modifier,
icon = MeshtasticIcons.Elevation, icon = MeshtasticIcons.Elevation,
contentDescription = stringResource(R.string.altitude), contentDescription = stringResource(R.string.altitude),
text = altitude.metersIn(system).toString(system) + " " + suffix, text = altitude.metersIn(system).toString(system) + " " + suffix,
contentColor = contentColor,
) )
} }
@@ -26,6 +26,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -40,6 +41,7 @@ fun IconInfo(
contentDescription: String, contentDescription: String,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
text: String? = null, text: String? = null,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
content: @Composable () -> Unit = {}, content: @Composable () -> Unit = {},
) { ) {
Row( Row(
@@ -51,11 +53,9 @@ fun IconInfo(
modifier = Modifier.size(SIZE_ICON.dp), modifier = Modifier.size(SIZE_ICON.dp),
imageVector = icon, imageVector = icon,
contentDescription = contentDescription, contentDescription = contentDescription,
tint = MaterialTheme.colorScheme.onSurface, tint = contentColor,
) )
text?.let { text?.let { Text(text = it, style = MaterialTheme.typography.labelMedium, color = contentColor) }
Text(text = it, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurface)
}
content() content()
} }
} }
@@ -17,8 +17,10 @@
package org.meshtastic.feature.node.component package org.meshtastic.feature.node.component
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
@@ -28,12 +30,18 @@ import org.meshtastic.core.ui.R
import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.AppTheme
@Composable @Composable
fun LastHeardInfo(modifier: Modifier = Modifier, lastHeard: Int, currentTimeMillis: Long) { fun LastHeardInfo(
modifier: Modifier = Modifier,
lastHeard: Int,
currentTimeMillis: Long,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
) {
IconInfo( IconInfo(
modifier = modifier, modifier = modifier,
icon = ImageVector.vectorResource(id = R.drawable.ic_antenna_24), icon = ImageVector.vectorResource(id = R.drawable.ic_antenna_24),
contentDescription = stringResource(org.meshtastic.core.strings.R.string.node_sort_last_heard), contentDescription = stringResource(org.meshtastic.core.strings.R.string.node_sort_last_heard),
text = formatAgo(lastHeard, currentTimeMillis), text = formatAgo(lastHeard, currentTimeMillis),
contentColor = contentColor,
) )
} }
@@ -32,7 +32,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor import androidx.compose.material3.contentColorFor
@@ -95,9 +94,9 @@ fun NodeItem(
val style = val style =
if (thatNode.isUnknownUser) { if (thatNode.isUnknownUser) {
LocalTextStyle.current.copy(fontStyle = FontStyle.Italic) FontStyle.Italic
} else { } else {
LocalTextStyle.current FontStyle.Normal
} }
val unmessageable = val unmessageable =
@@ -125,14 +124,15 @@ fun NodeItem(
Text( Text(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
text = longName, text = longName,
style = style = MaterialTheme.typography.titleMediumEmphasized.copy(fontStyle = style),
MaterialTheme.typography.titleMediumEmphasized.copy(
color = MaterialTheme.colorScheme.onSurface,
),
textDecoration = TextDecoration.LineThrough.takeIf { isIgnored }, textDecoration = TextDecoration.LineThrough.takeIf { isIgnored },
softWrap = true, softWrap = true,
) )
LastHeardInfo(lastHeard = thatNode.lastHeard, currentTimeMillis = currentTimeMillis) LastHeardInfo(
lastHeard = thatNode.lastHeard,
currentTimeMillis = currentTimeMillis,
contentColor = contentColor,
)
NodeStatusIcons( NodeStatusIcons(
isThisNode = isThisNode, isThisNode = isThisNode,
isFavorite = isFavorite, isFavorite = isFavorite,
@@ -148,23 +148,28 @@ fun NodeItem(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
MaterialBatteryInfo(level = thatNode.batteryLevel, voltage = thatNode.voltage) MaterialBatteryInfo(
level = thatNode.batteryLevel,
voltage = thatNode.voltage,
contentColor = contentColor,
)
Row( Row(
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
if (distance != null) { if (distance != null) {
DistanceInfo(distance = distance) DistanceInfo(distance = distance, contentColor = contentColor)
} }
thatNode.validPosition?.let { position -> thatNode.validPosition?.let { position ->
ElevationInfo( ElevationInfo(
altitude = position.altitude, altitude = position.altitude,
system = system, system = system,
suffix = stringResource(id = R.string.elevation_suffix), suffix = stringResource(id = R.string.elevation_suffix),
contentColor = contentColor,
) )
val satCount = position.satsInView val satCount = position.satsInView
if (satCount > 0) { if (satCount > 0) {
SatelliteCountInfo(satCount = satCount) SatelliteCountInfo(satCount = satCount, contentColor = contentColor)
} }
} }
} }
@@ -175,7 +180,7 @@ fun NodeItem(
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
itemVerticalAlignment = Alignment.CenterVertically, itemVerticalAlignment = Alignment.CenterVertically,
) { ) {
SignalInfo(node = thatNode, isThisNode = isThisNode) SignalInfo(node = thatNode, isThisNode = isThisNode, contentColor = contentColor)
} }
val telemetryStrings = thatNode.getTelemetryStrings(tempInFahrenheit) val telemetryStrings = thatNode.getTelemetryStrings(tempInFahrenheit)
@@ -183,11 +188,7 @@ fun NodeItem(
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
telemetryStrings.forEach { telemetryString -> telemetryStrings.forEach { telemetryString ->
Text( Text(text = telemetryString, style = MaterialTheme.typography.bodySmall, color = contentColor)
text = telemetryString,
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodySmall,
)
} }
} }
} }
@@ -199,12 +200,9 @@ fun NodeItem(
) { ) {
val labelStyle = val labelStyle =
if (thatNode.isUnknownUser) { if (thatNode.isUnknownUser) {
MaterialTheme.typography.labelSmall.copy( MaterialTheme.typography.labelSmall.copy(fontStyle = FontStyle.Italic)
fontStyle = FontStyle.Italic,
color = MaterialTheme.colorScheme.onSurface,
)
} else { } else {
MaterialTheme.typography.labelSmall.copy(color = MaterialTheme.colorScheme.onSurface) MaterialTheme.typography.labelSmall
} }
Text(text = thatNode.user.hwModel.name, style = labelStyle) Text(text = thatNode.user.hwModel.name, style = labelStyle)
Text(text = thatNode.user.role.name, style = labelStyle) Text(text = thatNode.user.role.name, style = labelStyle)
@@ -19,19 +19,26 @@ package org.meshtastic.feature.node.component
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.twotone.SatelliteAlt import androidx.compose.material.icons.twotone.SatelliteAlt
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.AppTheme
@Composable @Composable
fun SatelliteCountInfo(modifier: Modifier = Modifier, satCount: Int) { fun SatelliteCountInfo(
modifier: Modifier = Modifier,
satCount: Int,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
) {
IconInfo( IconInfo(
modifier = modifier, modifier = modifier,
icon = Icons.TwoTone.SatelliteAlt, icon = Icons.TwoTone.SatelliteAlt,
contentDescription = stringResource(org.meshtastic.core.strings.R.string.sats), contentDescription = stringResource(org.meshtastic.core.strings.R.string.sats),
text = "$satCount", text = "$satCount",
contentColor = contentColor,
) )
} }