Add dividers to node details (#3466)

This commit is contained in:
Phil Oliver 2025-10-14 22:06:45 -04:00 committed by GitHub
parent d64825f4f4
commit 73b37c17dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 122 additions and 6 deletions

View file

@ -22,7 +22,6 @@ import androidx.compose.material.icons.filled.ForkLeft
import androidx.compose.material.icons.filled.Icecream
import androidx.compose.material.icons.filled.Memory
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -35,6 +34,7 @@ import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
@ -61,6 +61,9 @@ fun AdministrationSection(
trailingIcon = null,
onClick = { onAction(NodeDetailAction.TriggerServiceAction(ServiceAction.GetDeviceMetadata(node.num))) },
)
InsetDivider()
ListItem(
text = stringResource(id = R.string.remote_admin),
leadingIcon = Icons.Default.Settings,
@ -95,6 +98,8 @@ fun AdministrationSection(
val deviceVersion = DeviceVersion(firmwareVersion.substringBeforeLast("."))
val statusColor = deviceVersion.determineFirmwareStatusColor(latestStable, latestAlpha)
InsetDivider()
ListItem(
text = stringResource(R.string.installed_firmware_version),
leadingIcon = Icons.Default.Memory,
@ -103,7 +108,9 @@ fun AdministrationSection(
leadingIconTint = statusColor,
trailingIcon = null,
)
HorizontalDivider()
InsetDivider()
ListItem(
text = stringResource(R.string.latest_stable_firmware),
leadingIcon = Icons.Default.Memory,
@ -113,6 +120,9 @@ fun AdministrationSection(
trailingIcon = null,
onClick = { onFirmwareSelect(latestStable) },
)
InsetDivider()
ListItem(
text = stringResource(R.string.latest_alpha_firmware),
leadingIcon = Icons.Default.Memory,

View file

@ -35,6 +35,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.SwitchListItem
import org.meshtastic.core.ui.component.TitledCard
@ -74,8 +75,12 @@ fun DeviceActions(
onClick = { onAction(NodeDetailAction.ShareContact) },
)
if (!isLocal) {
InsetDivider()
RemoteDeviceActions(node = node, lastTracerouteTime = lastTracerouteTime, onAction = onAction)
}
InsetDivider()
SwitchListItem(
text = stringResource(R.string.favorite),
leadingIcon = if (node.isFavorite) Icons.Default.Star else Icons.Default.StarBorder,
@ -83,6 +88,9 @@ fun DeviceActions(
checked = node.isFavorite,
onClick = { displayFavoriteDialog = true },
)
InsetDivider()
SwitchListItem(
text = stringResource(R.string.ignore),
leadingIcon =
@ -90,6 +98,9 @@ fun DeviceActions(
checked = node.isIgnored,
onClick = { displayIgnoreDialog = true },
)
InsetDivider()
ListItem(
text = stringResource(id = R.string.remove),
leadingIcon = Icons.Rounded.Delete,

View file

@ -45,6 +45,7 @@ import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
@ -58,6 +59,8 @@ fun DeviceDetailsSection(state: MetricsState, modifier: Modifier = Modifier) {
val hwModelName = deviceHardware.displayName
val isSupported = deviceHardware.activelySupported
TitledCard(stringResource(R.string.device), modifier = modifier) {
Spacer(modifier = Modifier.height(16.dp))
Box(
modifier =
Modifier.align(Alignment.CenterHorizontally)
@ -71,6 +74,8 @@ fun DeviceDetailsSection(state: MetricsState, modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.height(16.dp))
InsetDivider()
ListItem(
text = stringResource(R.string.hardware),
leadingIcon = Icons.Default.Router,
@ -78,6 +83,9 @@ fun DeviceDetailsSection(state: MetricsState, modifier: Modifier = Modifier) {
copyable = true,
trailingIcon = null,
)
InsetDivider()
ListItem(
text =
if (isSupported) {

View file

@ -45,6 +45,7 @@ import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.formatAgo
import org.meshtastic.core.model.util.formatUptime
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.node.model.isEffectivelyUnmessageable
@ -87,6 +88,9 @@ private fun MainNodeDetails(node: Node) {
copyable = true,
trailingIcon = null,
)
InsetDivider()
ListItem(
text = stringResource(R.string.short_name),
leadingIcon = Icons.Outlined.Person,
@ -94,6 +98,9 @@ private fun MainNodeDetails(node: Node) {
copyable = true,
trailingIcon = null,
)
InsetDivider()
ListItem(
text = stringResource(R.string.node_number),
leadingIcon = Icons.Default.Numbers,
@ -101,6 +108,9 @@ private fun MainNodeDetails(node: Node) {
copyable = true,
trailingIcon = null,
)
InsetDivider()
ListItem(
text = stringResource(R.string.user_id),
leadingIcon = Icons.Default.Person,
@ -108,13 +118,19 @@ private fun MainNodeDetails(node: Node) {
copyable = true,
trailingIcon = null,
)
InsetDivider()
ListItem(
text = stringResource(R.string.role),
leadingIcon = Icons.Default.Work,
supportingText = node.user.role.name,
trailingIcon = null,
)
if (node.isEffectivelyUnmessageable) {
InsetDivider()
ListItem(
text = stringResource(R.string.unmonitored_or_infrastructure),
leadingIcon = Icons.Outlined.NoCell,
@ -122,6 +138,8 @@ private fun MainNodeDetails(node: Node) {
)
}
if (node.deviceMetrics.uptimeSeconds > 0) {
InsetDivider()
ListItem(
text = stringResource(R.string.uptime),
leadingIcon = Icons.Default.CheckCircle,
@ -129,6 +147,9 @@ private fun MainNodeDetails(node: Node) {
trailingIcon = null,
)
}
InsetDivider()
ListItem(
text = stringResource(R.string.node_sort_last_heard),
leadingIcon = Icons.Default.History,

View file

@ -29,6 +29,7 @@ import androidx.compose.ui.unit.dp
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.toDistanceString
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.node.model.LogsType
@ -60,6 +61,8 @@ fun PositionSection(
// Distance (if available)
if (distance != null && distance.isNotEmpty()) {
InsetDivider()
ListItem(
text = stringResource(R.string.node_sort_distance),
leadingIcon = Icons.Default.SocialDistance,
@ -69,6 +72,8 @@ fun PositionSection(
)
}
InsetDivider()
// Exchange position action
ListItem(
text = stringResource(id = R.string.exchange_position),
@ -79,6 +84,8 @@ fun PositionSection(
// Node Map log
if (availableLogs.contains(LogsType.NODE_MAP)) {
InsetDivider()
ListItem(text = stringResource(LogsType.NODE_MAP.titleRes), leadingIcon = LogsType.NODE_MAP.icon) {
onAction(NodeDetailAction.Navigate(LogsType.NODE_MAP.route))
}
@ -86,6 +93,8 @@ fun PositionSection(
// Positions Log
if (availableLogs.contains(LogsType.POSITIONS)) {
InsetDivider()
ListItem(text = stringResource(LogsType.POSITIONS.titleRes), leadingIcon = LogsType.POSITIONS.icon) {
onAction(NodeDetailAction.Navigate(LogsType.POSITIONS.route))
}

View file

@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.feature.node.model.NodeDetailAction
import org.meshtastic.feature.node.model.isEffectivelyUnmessageable
@ -37,13 +38,19 @@ internal fun RemoteDeviceActions(node: Node, lastTracerouteTime: Long?, onAction
trailingIcon = null,
onClick = { onAction(NodeDetailAction.HandleNodeMenuAction(NodeMenuAction.DirectMessage(node))) },
)
InsetDivider()
}
ListItem(
text = stringResource(id = R.string.exchange_userinfo),
leadingIcon = Icons.Default.Person,
trailingIcon = null,
onClick = { onAction(NodeDetailAction.HandleNodeMenuAction(NodeMenuAction.RequestUserInfo(node))) },
)
InsetDivider()
TracerouteButton(
lastTracerouteTime = lastTracerouteTime,
onClick = { onAction(NodeDetailAction.HandleNodeMenuAction(NodeMenuAction.TraceRoute(node))) },