update reaction design

This commit is contained in:
2026-09-07 18:40:14 +07:00
parent c4d3870a02
commit 91817d7061
@@ -5,10 +5,9 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
@@ -27,7 +26,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.boundsInWindow
@@ -187,6 +185,15 @@ fun ChatMessage(
), ),
horizontalAlignment = if (model.isMine) Alignment.End else Alignment.Start, horizontalAlignment = if (model.isMine) Alignment.End else Alignment.Start,
verticalArrangement = Arrangement.spacedBy(4.dp) verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Box(contentAlignment = Alignment.BottomEnd) {
Column(
modifier = Modifier.padding(
bottom = if (model.reactions.isNotEmpty()) 4.dp else 0.dp,
end = if (model.reactions.isNotEmpty() && !model.isMine) 8.dp else 0.dp
),
horizontalAlignment = if (model.isMine) Alignment.End else Alignment.Start,
verticalArrangement = Arrangement.spacedBy(4.dp)
) { ) {
if (model.annotatedContent.isNotBlank()) { if (model.annotatedContent.isNotBlank()) {
Surface( Surface(
@@ -218,78 +225,69 @@ fun ChatMessage(
) )
} }
} }
}
if (model.reactions.isNotEmpty()) { if (model.reactions.isNotEmpty()) {
ReactionsRow( MessageReactions(
reactions = model.reactions, reactions = model.reactions,
modifier = Modifier.padding(top = 2.dp) modifier = Modifier.offset(y = 12.dp)
) )
} }
}
if (isMessageClicked) { if (isMessageClicked) {
Text( Text(
text = model.timestamp, text = model.timestamp,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.outline, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.align( modifier = Modifier.padding(top = if (model.reactions.isNotEmpty()) 8.dp else 0.dp)
if (model.isMine) Alignment.End else Alignment.Start
)
) )
} }
} }
} }
} }
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
private fun ReactionsRow( private fun MessageReactions(
reactions: List<ReactionGroup>, reactions: List<ReactionGroup>,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
FlowRow( val totalCount = reactions.sumOf { it.authors.size }
modifier = modifier, val displayEmojis = reactions.take(3).map { it.emoji }
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
reactions.forEach { group ->
ReactionChip(group)
}
}
}
@Composable
private fun ReactionChip(group: ReactionGroup) {
val backgroundColor = if (group.containsMe) {
MaterialTheme.colorScheme.secondaryContainer
} else {
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
}
val contentColor = if (group.containsMe) {
MaterialTheme.colorScheme.onSecondaryContainer
} else {
MaterialTheme.colorScheme.onSurfaceVariant
}
Surface(
color = backgroundColor,
contentColor = contentColor,
shape = CircleShape,
modifier = Modifier.padding(vertical = 2.dp)
) {
Row( Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), modifier = modifier,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp) horizontalArrangement = Arrangement.spacedBy(4.dp)
) { ) {
Text(text = group.emoji, fontSize = 14.sp) displayEmojis.forEach { emoji ->
if (group.authors.size > 1) { Surface(
modifier = Modifier.size(24.dp),
color = MaterialTheme.colorScheme.surface,
shape = CircleShape,
) {
Box(contentAlignment = Alignment.Center) {
Text( Text(
text = group.authors.size.toString(), text = emoji,
style = MaterialTheme.typography.labelSmall, fontSize = 12.sp,
fontWeight = FontWeight.Bold
) )
} }
} }
} }
if (totalCount > 2) {
Surface(
modifier = Modifier.size(24.dp),
color = MaterialTheme.colorScheme.surface,
shape = CircleShape,
) {
Box(contentAlignment = Alignment.Center) {
Text(
text = totalCount.toString(),
style = MaterialTheme.typography.labelSmall,
fontSize = 10.sp,
)
}
}
}
}
} }