update reaction design
This commit is contained in:
@@ -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
|
||||||
@@ -188,42 +186,53 @@ 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)
|
||||||
) {
|
) {
|
||||||
if (model.annotatedContent.isNotBlank()) {
|
Box(contentAlignment = Alignment.BottomEnd) {
|
||||||
Surface(
|
Column(
|
||||||
modifier = Modifier.widthIn(max = 280.dp),
|
modifier = Modifier.padding(
|
||||||
color = containerColor,
|
bottom = if (model.reactions.isNotEmpty()) 4.dp else 0.dp,
|
||||||
contentColor = contentColor,
|
end = if (model.reactions.isNotEmpty() && !model.isMine) 8.dp else 0.dp
|
||||||
shape = bubbleShape,
|
),
|
||||||
|
horizontalAlignment = if (model.isMine) Alignment.End else Alignment.Start,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
if (model.annotatedContent.isNotBlank()) {
|
||||||
text = model.annotatedContent,
|
Surface(
|
||||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
modifier = Modifier.widthIn(max = 280.dp),
|
||||||
style = MaterialTheme.typography.bodyLarge
|
color = containerColor,
|
||||||
)
|
contentColor = contentColor,
|
||||||
|
shape = bubbleShape,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = model.annotatedContent,
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||||
|
style = MaterialTheme.typography.bodyLarge
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.images.forEach { imageUrl ->
|
||||||
|
Surface(
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
modifier = Modifier.widthIn(max = 280.dp)
|
||||||
|
) {
|
||||||
|
AsyncImage(
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = "Image from chat",
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(RoundedCornerShape(16.dp)),
|
||||||
|
contentScale = ContentScale.FillWidth
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
model.images.forEach { imageUrl ->
|
|
||||||
Surface(
|
|
||||||
shape = RoundedCornerShape(16.dp),
|
|
||||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
|
||||||
modifier = Modifier.widthIn(max = 280.dp)
|
|
||||||
) {
|
|
||||||
AsyncImage(
|
|
||||||
model = imageUrl,
|
|
||||||
contentDescription = "Image from chat",
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clip(RoundedCornerShape(16.dp)),
|
|
||||||
contentScale = ContentScale.FillWidth
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
@@ -231,64 +240,53 @@ fun ChatMessage(
|
|||||||
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 }
|
||||||
|
val displayEmojis = reactions.take(3).map { it.emoji }
|
||||||
|
|
||||||
|
Row(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
reactions.forEach { group ->
|
displayEmojis.forEach { emoji ->
|
||||||
ReactionChip(group)
|
Surface(
|
||||||
|
modifier = Modifier.size(24.dp),
|
||||||
|
color = MaterialTheme.colorScheme.surface,
|
||||||
|
shape = CircleShape,
|
||||||
|
) {
|
||||||
|
Box(contentAlignment = Alignment.Center) {
|
||||||
|
Text(
|
||||||
|
text = emoji,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (totalCount > 2) {
|
||||||
}
|
Surface(
|
||||||
|
modifier = Modifier.size(24.dp),
|
||||||
@Composable
|
color = MaterialTheme.colorScheme.surface,
|
||||||
private fun ReactionChip(group: ReactionGroup) {
|
shape = CircleShape,
|
||||||
val backgroundColor = if (group.containsMe) {
|
) {
|
||||||
MaterialTheme.colorScheme.secondaryContainer
|
Box(contentAlignment = Alignment.Center) {
|
||||||
} else {
|
Text(
|
||||||
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
|
text = totalCount.toString(),
|
||||||
}
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
fontSize = 10.sp,
|
||||||
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(
|
|
||||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
|
||||||
) {
|
|
||||||
Text(text = group.emoji, fontSize = 14.sp)
|
|
||||||
if (group.authors.size > 1) {
|
|
||||||
Text(
|
|
||||||
text = group.authors.size.toString(),
|
|
||||||
style = MaterialTheme.typography.labelSmall,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user