diff --git a/app/src/main/java/com/geeksville/mesh/ui/BatteryInfo.kt b/app/src/main/java/com/geeksville/mesh/ui/BatteryInfo.kt new file mode 100644 index 000000000..8462f6c50 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/BatteryInfo.kt @@ -0,0 +1,83 @@ +package com.geeksville.mesh.ui + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.height +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp +import com.geeksville.mesh.R +import com.geeksville.mesh.ui.theme.AppTheme + +@Composable +fun BatteryInfo(batteryLevel: Int?, voltage: Float?) { + val infoString = "%d%% %.1fV".format(batteryLevel, voltage) + val (image, level) = when (batteryLevel) { + in 0 .. 4 -> R.drawable.ic_battery_alert to " $infoString" + in 5 .. 14 -> R.drawable.ic_battery_outline to infoString + in 15..34 -> R.drawable.ic_battery_low to infoString + in 35..79 -> R.drawable.ic_battery_medium to infoString + in 80..100 -> R.drawable.ic_battery_high to infoString + 101 -> R.drawable.ic_power_plug_24 to "%.1fV".format(voltage) + else -> R.drawable.ic_battery_unknown to (voltage?.let { "%.1fV".format(it) } ?: "") + } + + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + modifier = Modifier.height(18.dp), + imageVector = ImageVector.vectorResource(id = image), + contentDescription = null, + tint = MaterialTheme.colors.onSurface, + ) + Text( + text = level, + color = MaterialTheme.colors.onSurface, + fontSize = MaterialTheme.typography.button.fontSize + ) + } +} + +@Composable +@Preview(showBackground = true) +@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +fun BatteryInfoPreview( + @PreviewParameter(BatteryInfoPreviewParameterProvider::class) + batteryInfo: Pair +) { + AppTheme { + BatteryInfo(batteryInfo.first, batteryInfo.second) + } +} + +@Composable +@Preview +fun BatteryInfoPreviewSimple() { + AppTheme { + BatteryInfo(85, 3.7F) + } +} + +class BatteryInfoPreviewParameterProvider : PreviewParameterProvider> { + override val values: Sequence> + get() = sequenceOf( + 85 to 3.7F, + 2 to 3.7F, + 12 to 3.7F, + 28 to 3.7F, + 50 to 3.7F, + 101 to 4.9F, + null to 4.5F, + null to null + ) +} \ 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 94a5ed948..36bf10935 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt @@ -28,6 +28,7 @@ import com.geeksville.mesh.android.Logging import com.geeksville.mesh.databinding.AdapterNodeLayoutBinding import com.geeksville.mesh.databinding.NodelistFragmentBinding import com.geeksville.mesh.model.UIViewModel +import com.geeksville.mesh.ui.theme.AppTheme import com.geeksville.mesh.util.formatAgo import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint @@ -58,12 +59,11 @@ class UsersFragment : ScreenFragment("Users"), Logging { val nodeNameView = itemView.nodeNameView val distanceView = itemView.distanceView val coordsView = itemView.coordsView - val batteryPctView = itemView.batteryPercentageView val lastTime = itemView.lastConnectionView - val powerIcon = itemView.batteryIcon val signalView = itemView.signalView val envMetrics = itemView.envMetrics val background = itemView.nodeCard + val batteryInfo = itemView.batteryInfo fun blink() { val bg = background.backgroundTintList @@ -85,6 +85,14 @@ class UsersFragment : ScreenFragment("Users"), Logging { } } } + + fun bind(batteryLevel: Int?, voltage: Float?) { + batteryInfo.setContent { + AppTheme { + BatteryInfo(batteryLevel, voltage) + } + } + } } private val nodesAdapter = object : RecyclerView.Adapter() { @@ -232,6 +240,9 @@ class UsersFragment : ScreenFragment("Users"), Logging { val user = n.user val (textColor, nodeColor) = n.colors val isIgnored: Boolean = ignoreIncomingList.contains(n.num) + + holder.bind(n.batteryLevel, n.voltage) + with(holder.chipNode) { text = (user?.shortName ?: "UNK").strikeIf(isIgnored) chipBackgroundColor = ColorStateList.valueOf(nodeColor) @@ -260,7 +271,6 @@ class UsersFragment : ScreenFragment("Users"), Logging { } else { holder.distanceView.visibility = View.INVISIBLE } - renderBattery(n.batteryLevel, n.voltage, holder) holder.lastTime.text = formatAgo(n.lastHeard) @@ -312,24 +322,6 @@ class UsersFragment : ScreenFragment("Users"), Logging { } } - private fun renderBattery( - battery: Int?, - voltage: Float?, - holder: ViewHolder - ) { - - val (image, text) = when (battery) { - in 0..100 -> R.drawable.ic_battery_full_24 to "%d%% %.2fV".format(battery, voltage) - 101 -> R.drawable.ic_power_plug_24 to "" - else -> R.drawable.ic_battery_full_24 to "?" - } - - holder.batteryPctView.text = text - holder.powerIcon.setImageDrawable(context?.let { - ContextCompat.getDrawable(it, image) - }) - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? diff --git a/app/src/main/java/com/geeksville/mesh/ui/theme/Color.kt b/app/src/main/java/com/geeksville/mesh/ui/theme/Color.kt index adc0e933b..265a28315 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/theme/Color.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/theme/Color.kt @@ -15,4 +15,6 @@ val LightPink = Color(0xFFFFE6E6) val LightGreen = Color(0xFFCFE8A9) val LightRed = Color(0xFFFFB3B3) -val MeshtasticGreen = Color(0xFF67EA94) \ No newline at end of file +val MeshtasticGreen = Color(0xFF67EA94) +val AlmostWhite = Color(0xB3FFFFFF) +val AlmostBlack = Color(0x8A000000) \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/ui/theme/Theme.kt b/app/src/main/java/com/geeksville/mesh/ui/theme/Theme.kt index 0646ca402..261ddb617 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/theme/Theme.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/theme/Theme.kt @@ -7,15 +7,17 @@ import androidx.compose.material.lightColors import androidx.compose.runtime.Composable private val DarkColorPalette = darkColors( - primary = Purple200, + primary = MeshtasticGreen, primaryVariant = Purple700, - secondary = Teal200 + secondary = Teal200, + onSurface = AlmostWhite ) private val LightColorPalette = lightColors( - primary = SkyBlue, + primary = MeshtasticGreen, primaryVariant = LightSkyBlue, - secondary = Teal200 + secondary = Teal200, + onSurface = AlmostBlack /* Other default colors to override background = Color.White, diff --git a/app/src/main/res/drawable/ic_battery_alert.xml b/app/src/main/res/drawable/ic_battery_alert.xml new file mode 100644 index 000000000..aab98bc9d --- /dev/null +++ b/app/src/main/res/drawable/ic_battery_alert.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_battery_high.xml b/app/src/main/res/drawable/ic_battery_high.xml new file mode 100644 index 000000000..032956f30 --- /dev/null +++ b/app/src/main/res/drawable/ic_battery_high.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/drawable/ic_battery_low.xml b/app/src/main/res/drawable/ic_battery_low.xml new file mode 100644 index 000000000..2126c0bc3 --- /dev/null +++ b/app/src/main/res/drawable/ic_battery_low.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/drawable/ic_battery_medium.xml b/app/src/main/res/drawable/ic_battery_medium.xml new file mode 100644 index 000000000..e60a81575 --- /dev/null +++ b/app/src/main/res/drawable/ic_battery_medium.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_battery_outline.xml b/app/src/main/res/drawable/ic_battery_outline.xml new file mode 100644 index 000000000..ec515ed01 --- /dev/null +++ b/app/src/main/res/drawable/ic_battery_outline.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_battery_unknown.xml b/app/src/main/res/drawable/ic_battery_unknown.xml new file mode 100644 index 000000000..6be9c7145 --- /dev/null +++ b/app/src/main/res/drawable/ic_battery_unknown.xml @@ -0,0 +1,14 @@ + + + \ 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 7ddbdf324..2bc8a1ee3 100644 --- a/app/src/main/res/layout/adapter_node_layout.xml +++ b/app/src/main/res/layout/adapter_node_layout.xml @@ -1,9 +1,12 @@ - + android:clipToPadding="false" + > + android:layout_height="wrap_content" + android:padding="8dp" + > + app:layout_constraintTop_toTopOf="parent" + tools:text="@string/some_username" + /> + app:layout_constraintTop_toTopOf="@+id/chip_node" + tools:text="@string/unknown_username" + /> + android:layout_marginTop="8dp" + tools:text="@string/sample_distance" + /> + app:layout_constraintVertical_bias="0.0" + tools:text="@string/sample_coords" + /> - - - + tools:composableName="com.geeksville.mesh.ui.BatteryInfoKt.BatteryInfoPreviewSimple" + /> + tools:text="11h01 PM" + /> + tools:text="RSSI: -40 SNR: -8" + /> + app:layout_constraintStart_toStartOf="parent" + tools:visibility="visible" + />