dm-88
This commit is contained in:
parent
d362846f1b
commit
48ac1462c3
1 changed files with 122 additions and 120 deletions
|
|
@ -422,129 +422,131 @@ fun MessageRow(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//message container
|
Row() {
|
||||||
Row(
|
//message container
|
||||||
modifier = Modifier
|
Row(
|
||||||
.fillMaxWidth()
|
modifier = Modifier
|
||||||
.then(if (isHighlight) Modifier.background(Color(0x33FF9800), RoundedCornerShape(12.dp)) else Modifier)
|
.fillMaxWidth()
|
||||||
,
|
.then(if (isHighlight) Modifier.background(Color(0x33FF9800), RoundedCornerShape(12.dp)) else Modifier)
|
||||||
horizontalArrangement = if (isMe) Arrangement.End else Arrangement.Start
|
,
|
||||||
) {
|
horizontalArrangement = if (isMe) Arrangement.End else Arrangement.Start
|
||||||
if (!isMe) {
|
|
||||||
UserAvatar(
|
|
||||||
avatarUrl = partnerAvatarUrl,
|
|
||||||
modifier = Modifier.padding(end = 8.dp).size(32.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
|
||||||
horizontalAlignment = if (isMe) Alignment.End else Alignment.Start
|
|
||||||
) {
|
) {
|
||||||
Box(
|
if (!isMe) {
|
||||||
modifier = Modifier
|
UserAvatar(
|
||||||
.widthIn(max = 280.dp)
|
avatarUrl = partnerAvatarUrl,
|
||||||
// 💡 重點修正:將點擊/長按事件移到這裡,範圍只侷限在氣泡內
|
modifier = Modifier.padding(end = 8.dp).size(32.dp)
|
||||||
// 注意:剪裁形狀(clip)建議放在點擊事件前或與形狀同步,確保點擊時的水波紋(Indication)不會超出圓角
|
)
|
||||||
.clip(
|
|
||||||
RoundedCornerShape(
|
|
||||||
topStart = 12.dp, topEnd = 12.dp,
|
|
||||||
bottomStart = if (isMe) 12.dp else 0.dp,
|
|
||||||
bottomEnd = if (isMe) 0.dp else 12.dp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
//long press action short press react
|
|
||||||
.combinedClickable(
|
|
||||||
onLongClick = { onReplyClick(message) },
|
|
||||||
onClick = { onRowClick(message) }
|
|
||||||
)
|
|
||||||
.background(color = bubbleColor)
|
|
||||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
|
||||||
) {
|
|
||||||
Column {
|
|
||||||
// 💡 【核心:渲染被回覆的訊息內容】
|
|
||||||
message.repliedMessage?.let { replied ->
|
|
||||||
val repliedSenderName = if (replied.senderId == currentUserId) "你" else partnerDisplayName
|
|
||||||
|
|
||||||
// 被回覆的小氣泡外框
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 6.dp)
|
|
||||||
.clip(RoundedCornerShape(4.dp))
|
|
||||||
// 💡 修正這裡:直接根據 isMe 決定傳入哪一個 Color 物件即可
|
|
||||||
.background(if (isMe) Color(0xFFC7EBB2) else Color(0xFFE0E0E0))
|
|
||||||
.drawBehind {
|
|
||||||
// 在左側畫一條精緻的提示線 (類似 LINE / Telegram)
|
|
||||||
drawLine(
|
|
||||||
color = Color.Gray,
|
|
||||||
start = Offset(0f, 0f),
|
|
||||||
end = Offset(0f, size.height),
|
|
||||||
strokeWidth = 6f
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp, end = 4.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Column {
|
|
||||||
Text(
|
|
||||||
text = repliedSenderName,
|
|
||||||
style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold),
|
|
||||||
color = Color(0xFF1E88E5),
|
|
||||||
maxLines = 1
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
// 如果被回覆的是圖片,顯示 [圖片],否則顯示文字內容
|
|
||||||
text = if (replied.attachment?.mimeType?.startsWith("image/") == true) "[圖片]" else replied.content,
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = Color.DarkGray,
|
|
||||||
maxLines = 1, // 最多一行,避免太長
|
|
||||||
overflow = TextOverflow.Ellipsis
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 原本的訊息主體內容(文字或圖片)
|
|
||||||
if (isImage) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = 4.dp)
|
|
||||||
.widthIn(max = 240.dp)
|
|
||||||
.clip(RoundedCornerShape(8.dp))
|
|
||||||
.background(Color.LightGray)
|
|
||||||
) {
|
|
||||||
AsyncImage(
|
|
||||||
model = finalImageModel,
|
|
||||||
contentDescription = "聊天圖片",
|
|
||||||
contentScale = ContentScale.Fit,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.heightIn(max = 300.dp),
|
|
||||||
// 🛠️ 移除了 unresolved 的 debugPlaceholder
|
|
||||||
onError = { errorState ->
|
|
||||||
// 這樣就能在 Logcat 裡過濾 "ChatImageError" 關鍵字,看看到底是哪個網址拼錯了!
|
|
||||||
android.util.Log.e(
|
|
||||||
"ChatImageError",
|
|
||||||
"圖片載入失敗, 網址為: $finalImageModel, 原因: ${errorState.result.throwable}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Text(
|
|
||||||
text = rawContent,
|
|
||||||
style = MaterialTheme.typography.bodyMedium
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 ✨ 新增:如果這條訊息有 Reaction,就顯示在氣泡的正下方
|
Column(
|
||||||
if (!message.reactions.isNullOrEmpty()) {
|
horizontalAlignment = if (isMe) Alignment.End else Alignment.Start
|
||||||
ReactionRow(
|
) {
|
||||||
reactions = message.reactions,
|
Box(
|
||||||
onReactionClick = { emoji -> onReactionClick(message, emoji) }
|
modifier = Modifier
|
||||||
)
|
.widthIn(max = 280.dp)
|
||||||
|
// 💡 重點修正:將點擊/長按事件移到這裡,範圍只侷限在氣泡內
|
||||||
|
// 注意:剪裁形狀(clip)建議放在點擊事件前或與形狀同步,確保點擊時的水波紋(Indication)不會超出圓角
|
||||||
|
.clip(
|
||||||
|
RoundedCornerShape(
|
||||||
|
topStart = 12.dp, topEnd = 12.dp,
|
||||||
|
bottomStart = if (isMe) 12.dp else 0.dp,
|
||||||
|
bottomEnd = if (isMe) 0.dp else 12.dp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
//long press action short press react
|
||||||
|
.combinedClickable(
|
||||||
|
onLongClick = { onReplyClick(message) },
|
||||||
|
onClick = { onRowClick(message) }
|
||||||
|
)
|
||||||
|
.background(color = bubbleColor)
|
||||||
|
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
Column {
|
||||||
|
// 💡 【核心:渲染被回覆的訊息內容】
|
||||||
|
message.repliedMessage?.let { replied ->
|
||||||
|
val repliedSenderName = if (replied.senderId == currentUserId) "你" else partnerDisplayName
|
||||||
|
|
||||||
|
// 被回覆的小氣泡外框
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 6.dp)
|
||||||
|
.clip(RoundedCornerShape(4.dp))
|
||||||
|
// 💡 修正這裡:直接根據 isMe 決定傳入哪一個 Color 物件即可
|
||||||
|
.background(if (isMe) Color(0xFFC7EBB2) else Color(0xFFE0E0E0))
|
||||||
|
.drawBehind {
|
||||||
|
// 在左側畫一條精緻的提示線 (類似 LINE / Telegram)
|
||||||
|
drawLine(
|
||||||
|
color = Color.Gray,
|
||||||
|
start = Offset(0f, 0f),
|
||||||
|
end = Offset(0f, size.height),
|
||||||
|
strokeWidth = 6f
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp, end = 4.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = repliedSenderName,
|
||||||
|
style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold),
|
||||||
|
color = Color(0xFF1E88E5),
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
// 如果被回覆的是圖片,顯示 [圖片],否則顯示文字內容
|
||||||
|
text = if (replied.attachment?.mimeType?.startsWith("image/") == true) "[圖片]" else replied.content,
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = Color.DarkGray,
|
||||||
|
maxLines = 1, // 最多一行,避免太長
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 原本的訊息主體內容(文字或圖片)
|
||||||
|
if (isImage) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp)
|
||||||
|
.widthIn(max = 240.dp)
|
||||||
|
.clip(RoundedCornerShape(8.dp))
|
||||||
|
.background(Color.LightGray)
|
||||||
|
) {
|
||||||
|
AsyncImage(
|
||||||
|
model = finalImageModel,
|
||||||
|
contentDescription = "聊天圖片",
|
||||||
|
contentScale = ContentScale.Fit,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.heightIn(max = 300.dp),
|
||||||
|
// 🛠️ 移除了 unresolved 的 debugPlaceholder
|
||||||
|
onError = { errorState ->
|
||||||
|
// 這樣就能在 Logcat 裡過濾 "ChatImageError" 關鍵字,看看到底是哪個網址拼錯了!
|
||||||
|
android.util.Log.e(
|
||||||
|
"ChatImageError",
|
||||||
|
"圖片載入失敗, 網址為: $finalImageModel, 原因: ${errorState.result.throwable}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Text(
|
||||||
|
text = rawContent,
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 💡 ✨ 新增:如果這條訊息有 Reaction,就顯示在氣泡的正下方
|
||||||
|
if (!message.reactions.isNullOrEmpty()) {
|
||||||
|
ReactionRow(
|
||||||
|
reactions = message.reactions,
|
||||||
|
onReactionClick = { emoji -> onReactionClick(message, emoji) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue