Fix layout issues

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2026-02-12 13:08:14 +03:00
Unverified
parent 9fa3b31744
commit c6a9e32a48
@@ -11,6 +11,7 @@ import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
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.BoxWithConstraints
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -90,143 +91,135 @@ fun MessageItem(
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
} }
Column( BoxWithConstraints(
modifier = Modifier modifier = Modifier.weight(1f, fill = false)
.weight(1f, fill = false)
.widthIn(max = 280.dp),
horizontalAlignment = if (isAuthor) Alignment.End else Alignment.Start
) { ) {
// Message bubble // Allow bubbles to grow up to 70% of the available row width
val isDark = isSystemInDarkTheme() val maxBubbleWidth = maxWidth * 0.7f
Box(
modifier = Modifier Column(
.width(IntrinsicSize.Min) horizontalAlignment = if (isAuthor) Alignment.End else Alignment.Start
.clip(
RoundedCornerShape(
topStart = 20.dp,
topEnd = 20.dp,
bottomStart = if (isAuthor) 20.dp else 8.dp,
bottomEnd = if (isAuthor) 8.dp else 20.dp
)
)
.conditional(
isAuthor,
`if` = {
it
.shadow(
elevation = 8.dp,
shape = RoundedCornerShape(
topStart = 20.dp,
topEnd = 20.dp,
bottomStart = 20.dp,
bottomEnd = 8.dp
),
spotColor = if (isDark) Color(0x66000000) else Color(0x33000000)
)
.background(getMessageGradient(isDark))
},
`else` = {
background(MaterialTheme.colorScheme.surfaceContainerHighest)
}
)
.padding(top = 6.dp)
) { ) {
Column { // Message bubble
// Username inside bubble (for received messages) val isDark = isSystemInDarkTheme()
if (showUsername && !isAuthor) { Box(
Text( modifier = Modifier
text = message.username, // Max width: 70% of row, min width: content-driven
style = MaterialTheme.typography.labelMedium, .widthIn(max = maxBubbleWidth)
fontWeight = FontWeight.SemiBold, .clip(
color = MaterialTheme.colorScheme.primary, RoundedCornerShape(
modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 4.dp) topStart = 20.dp,
topEnd = 20.dp,
bottomStart = if (isAuthor) 20.dp else 8.dp,
bottomEnd = if (isAuthor) 8.dp else 20.dp
)
) )
} .conditional(
isAuthor,
// Reply preview `if` = {
message.reply_to?.let { replyTo -> it
Box( .shadow(
Modifier.padding(bottom = 4.dp, start = 6.dp, end = 6.dp) elevation = 8.dp,
) { shape = RoundedCornerShape(
Row( topStart = 20.dp,
modifier = Modifier topEnd = 20.dp,
.clip(RoundedCornerShape(12.dp)) bottomStart = 20.dp,
.fillMaxWidth() bottomEnd = 8.dp
.height(IntrinsicSize.Min) ),
.conditional( spotColor = if (isDark) Color(0x66000000) else Color(0x33000000)
isAuthor,
`if` = {
background(getReplyMessageGradient(isDark))
},
`else` = {
background(MaterialTheme.colorScheme.surfaceVariant)
}
) )
) { .background(getMessageGradient(isDark))
Box( },
Modifier `else` = {
.background(MaterialTheme.colorScheme.primary) background(MaterialTheme.colorScheme.surfaceContainerHighest)
.width(3.dp) }
.fillMaxHeight() )
) .padding(top = 6.dp)
) {
Column {
// Username inside bubble (for received messages)
if (showUsername && !isAuthor) {
Text(
text = message.username,
style = MaterialTheme.typography.labelMedium,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 4.dp)
)
}
Column( // Reply preview
Modifier.padding(horizontal = 8.dp, vertical = 6.dp) message.reply_to?.let { replyTo ->
Box(
Modifier.padding(bottom = 4.dp, start = 6.dp, end = 6.dp)
) {
Row(
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.fillMaxWidth()
.height(IntrinsicSize.Min)
.conditional(
isAuthor,
`if` = {
background(getReplyMessageGradient(isDark))
},
`else` = {
background(MaterialTheme.colorScheme.surfaceVariant)
}
)
) { ) {
if (showUsername) { Box(
Modifier
.background(MaterialTheme.colorScheme.primary)
.width(3.dp)
.fillMaxHeight()
)
Column(
Modifier.padding(horizontal = 8.dp, vertical = 6.dp)
) {
if (showUsername) {
Text(
text = replyTo.username,
style = MaterialTheme.typography.labelSmall,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.primary,
fontSize = 11.sp
)
}
Text( Text(
text = replyTo.username, text = replyTo.content.take(50) + if (replyTo.content.length > 50) "..." else "",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.bodySmall,
fontWeight = FontWeight.SemiBold, color = MaterialTheme.colorScheme.onSurfaceVariant,
color = MaterialTheme.colorScheme.primary, fontSize = 12.sp,
fontSize = 11.sp maxLines = 1
) )
} }
Text(
text = replyTo.content.take(50) + if (replyTo.content.length > 50) "..." else "",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontSize = 12.sp,
maxLines = 1
)
} }
} }
} }
}
// Message content // Message content
Text(
text = message.content,
style = MaterialTheme.typography.bodyMedium,
color = if (isAuthor) {
Color.White
} else {
MaterialTheme.colorScheme.onSurface
},
modifier = Modifier.padding(horizontal = 12.dp)
)
// Timestamp and edited indicator
Row(
modifier = Modifier
.padding(start = 12.dp, end = 12.dp, top = 4.dp, bottom = 8.dp),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically
) {
Text( Text(
text = formatTime(message.timestamp), text = message.content,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.bodyMedium,
fontSize = 11.sp,
color = if (isAuthor) { color = if (isAuthor) {
Color.White.copy(alpha = 0.7f) Color.White
} else { } else {
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f) MaterialTheme.colorScheme.onSurface
} },
modifier = Modifier.padding(horizontal = 12.dp)
) )
if (message.is_edited) {
Spacer(modifier = Modifier.width(4.dp)) // Timestamp and edited indicator
Row(
modifier = Modifier
.padding(start = 12.dp, end = 12.dp, top = 4.dp, bottom = 8.dp),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically
) {
Text( Text(
text = "(edited)", text = formatTime(message.timestamp),
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
fontSize = 11.sp, fontSize = 11.sp,
color = if (isAuthor) { color = if (isAuthor) {
@@ -235,6 +228,19 @@ fun MessageItem(
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f) MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
} }
) )
if (message.is_edited) {
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "(edited)",
style = MaterialTheme.typography.labelSmall,
fontSize = 11.sp,
color = if (isAuthor) {
Color.White.copy(alpha = 0.7f)
} else {
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
}
)
}
} }
} }
} }