Refactor: Improve UI consistency and animations (#2226)

This commit is contained in:
James Rich 2025-06-22 19:26:36 +00:00 committed by GitHub
parent 0b19f842bb
commit 1d165a5dc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 43 additions and 18 deletions

View file

@ -25,6 +25,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
@ -50,6 +51,7 @@ fun AutoLinkText(
modifier: Modifier = Modifier,
style: TextStyle = TextStyle.Default,
linkStyles: TextLinkStyles = DefaultTextLinkStyles,
color: Color = Color.Unspecified,
) {
val spannable = remember(text) {
linkify(text)
@ -57,7 +59,7 @@ fun AutoLinkText(
Text(
text = spannable.toAnnotatedString(linkStyles),
modifier = modifier,
style = style,
style = style.copy(color = color),
)
}

View file

@ -172,6 +172,7 @@ internal fun MessageList(
mutableStateOf(nodes.find { it.num == msg.node.num } ?: msg.node)
}
MessageItem(
modifier = Modifier.animateItem(),
node = node,
ourNode = ourNode!!,
message = msg,

View file

@ -33,6 +33,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.FormatQuote
import androidx.compose.material3.Card
import androidx.compose.material3.CardColors
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
@ -89,11 +90,17 @@ internal fun MessageItem(
.background(color = if (selected) Color.Gray else MaterialTheme.colorScheme.background),
) {
val fromLocal = node.user.id == DataPacket.ID_LOCAL
val messageColor = if (fromLocal) {
Color(ourNode.colors.second).copy(alpha = 0.25f)
} else {
Color(node.colors.second).copy(alpha = 0.25f)
}
val containerColor = Color(
if (fromLocal) {
ourNode.colors.second
} else {
node.colors.second
}
).copy(alpha = 0.2f)
val cardColors = CardDefaults.cardColors().copy(
containerColor = containerColor,
contentColor = contentColorFor(containerColor)
)
val messageModifier = Modifier.padding(start = 8.dp, top = 8.dp, end = 8.dp)
Box {
Card(
@ -109,17 +116,18 @@ internal fun MessageItem(
onLongClick = onLongClick,
)
.then(messageModifier),
colors = CardDefaults.cardColors(
containerColor = messageColor,
contentColor = contentColorFor(messageColor),
),
colors = cardColors,
) {
Column(
modifier = Modifier
.fillMaxWidth(),
) {
ReplyingTo(message, ourNode, onNavigateToOriginalMessage)
ReplyingTo(
message = message,
ourNode = ourNode,
cardColors = cardColors,
onNavigateToOriginalMessage = onNavigateToOriginalMessage
)
Row(
modifier = Modifier
.fillMaxWidth()
@ -154,6 +162,7 @@ internal fun MessageItem(
.padding(horizontal = 8.dp),
text = message.text,
style = MaterialTheme.typography.bodyMedium,
color = cardColors.contentColor
)
Row(
modifier = Modifier
@ -208,6 +217,7 @@ internal fun MessageItem(
private fun ReplyingTo(
message: Message,
ourNode: Node,
cardColors: CardColors = CardDefaults.cardColors(),
onNavigateToOriginalMessage: (Int) -> Unit
) {
message.originalMessage?.let { originalMessage ->
@ -219,10 +229,7 @@ private fun ReplyingTo(
modifier = Modifier
.fillMaxWidth()
.clickable { onNavigateToOriginalMessage(originalMessage.packetId) },
colors = CardDefaults.cardColors(
containerColor = Color(originalMessageNode.colors.second).copy(alpha = 0.5f),
contentColor = Color(originalMessageNode.colors.first),
),
colors = cardColors,
) {
Row(
modifier = Modifier.padding(horizontal = 4.dp),

View file

@ -18,7 +18,6 @@
package com.geeksville.mesh.ui.node
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
@ -115,7 +114,7 @@ fun NodeScreen(
items(nodes, key = { it.num }) { node ->
NodeItem(
modifier = Modifier.animateContentSize(),
modifier = Modifier.animateItem(),
thisNode = ourNode,
thatNode = node,
gpsFormat = state.gpsFormat,

View file

@ -29,15 +29,18 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
@ -96,6 +99,18 @@ fun NodeItem(
LocalTextStyle.current
}
val cardColors = if (isThisNode) {
thisNode?.colors?.second
} else {
thatNode.colors.second
}?.let {
val containerColor = Color(it).copy(alpha = 0.2f)
CardDefaults.cardColors().copy(
containerColor = containerColor,
contentColor = contentColorFor(containerColor)
)
} ?: (CardDefaults.cardColors())
val (detailsShown, showDetails) = remember { mutableStateOf(expanded) }
val unmessageable = remember(thatNode) {
when {
@ -110,6 +125,7 @@ fun NodeItem(
.padding(horizontal = 8.dp, vertical = 4.dp)
.defaultMinSize(minHeight = 80.dp),
onClick = { showDetails(!detailsShown) },
colors = cardColors
) {
Column(
modifier = Modifier