This commit is contained in:
Eric85710 2026-05-15 17:56:32 +08:00
parent 284e89924a
commit c22bbbcaa0

View file

@ -2,6 +2,7 @@ package com.example.login_v3.home.Message.UI
import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
@ -11,6 +12,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@ -273,7 +275,7 @@ fun Loaded_Tg_Message(
room = room, room = room,
onClick = onRoomClick onClick = onRoomClick
) )
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(6.dp))
} }
} }
} }
@ -296,92 +298,147 @@ fun RoomItem(
.clickable { onClick(room.roomId) }, .clickable { onClick(room.roomId) },
shape = RoundedCornerShape(16.dp), // 較大的圓角看起來更現代 shape = RoundedCornerShape(16.dp), // 較大的圓角看起來更現代
colors = CardDefaults.cardColors( colors = CardDefaults.cardColors(
containerColor = Color.White.copy(alpha = 0.85f) // 半透明白色,透出後方的漸層背景 containerColor = Color.Transparent // ✅ 透明背景
), ),
elevation = CardDefaults.cardElevation( elevation = CardDefaults.cardElevation(
defaultElevation = 0.dp // 增加輕微陰影 defaultElevation = 0.dp // 增加輕微陰影
) )
) { ) {
Row( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxSize()
.background(Color.Transparent) ){
.padding(16.dp), // Card 內部的填充 //glass effect
verticalAlignment = Alignment.CenterVertically Box(
) {
// 1. 頭像
val imageUrl = room.roomIconUrl ?: room.partner?.fullContactAvatarUrl
AsyncImage(
model = imageUrl,
contentDescription = "Avatar",
contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
.size(56.dp) // 稍微加大一點 .matchParentSize()
.clip(CircleShape) .blur(10.dp)
.border(1.dp, Color.White, CircleShape) // 頭像加個細白邊 )
.background(Color.LightGray) Box(
modifier = Modifier
.matchParentSize()
.background(
color = MaterialTheme.colorScheme.primary,
RoundedCornerShape(16.dp)
)
.border(
1.dp,
Color.White.copy(alpha = 0.3f),
RoundedCornerShape(16.dp)
)
) )
Spacer(modifier = Modifier.width(16.dp))
// 2. 中間內容 Row(
Column(modifier = Modifier.weight(1f)) { verticalAlignment = Alignment.CenterVertically,
Text( modifier = Modifier.padding(12.dp),
text = room.roomName.orEmpty().ifEmpty { ) {
room.partner?.displayName ?: "Unknown" // 1. 頭像
}, val imageUrl = room.roomIconUrl ?: room.partner?.fullContactAvatarUrl
style = MaterialTheme.typography.titleMedium, AsyncImage(
fontWeight = FontWeight.Bold, model = imageUrl,
color = Color(0xFF333333), contentDescription = "Avatar",
maxLines = 1, contentScale = ContentScale.Crop,
overflow = TextOverflow.Ellipsis modifier = Modifier
.size(56.dp) // 稍微加大一點
.clip(CircleShape)
.border(1.dp, Color.White, CircleShape) // 頭像加個細白邊
.background(Color.LightGray)
) )
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.width(16.dp))
val lastMsgText = when { // 2. 中間內容
room.lastMessage?.isDeleted == true -> "訊息已刪除" Column(
room.lastMessage?.content != null -> room.lastMessage.content modifier = Modifier.weight(1f)
room.lastMessage?.attachment != null -> "[檔案] ${room.lastMessage.attachment.filename}" ) {
else -> "尚未有訊息" Text(
text = room.roomName.orEmpty().ifEmpty {
room.partner?.displayName ?: "Unknown"
},
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = Color(0xFF333333),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Spacer(modifier = Modifier.height(4.dp))
val lastMsgText = when {
room.lastMessage?.isDeleted == true -> "訊息已刪除"
room.lastMessage?.content != null -> room.lastMessage.content
room.lastMessage?.attachment != null -> "[檔案] ${room.lastMessage.attachment.filename}"
else -> "尚未有訊息"
}
Row() {
Text(
text = lastMsgText,
style = MaterialTheme.typography.bodyMedium,
color = Color.Gray,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
if (room.unreadCount > 0) {
Badge(
containerColor = Color(0xFFDA7029), // 使用你的主橘色
contentColor = Color.White
) {
Text(
text = if (room.unreadCount > 99) "99+" else room.unreadCount.toString(),
modifier = Modifier.padding(horizontal = 4.dp)
)
}
}
}
Spacer(modifier = Modifier.width(2.dp))
} }
Text( // 3. 右側:時間與未讀計數
text = lastMsgText, Column(
style = MaterialTheme.typography.bodyMedium, verticalArrangement = Arrangement.Center
color = Color.Gray, ) {
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
// 3. 右側:時間與未讀計數 val partner = room.partner // 先從 room 取得 partner
Column( if (partner != null) {
horizontalAlignment = Alignment.End, val status = UserStatus.fromString(partner.status)
verticalArrangement = Arrangement.Center if (status != UserStatus.UNKNOWN) {
) { Canvas(
val time = room.lastMessage?.createdAt?.take(10) ?: "" modifier = Modifier
Text( .size(14.dp)
text = time, // 注意:在 Column 中 Alignment.BottomEnd 可能不適用
style = MaterialTheme.typography.labelSmall, // 如果你要讓點跟在文字旁邊,建議用 Box 或是調整 Alignment
color = Color.Gray .border(2.dp, Color.White, CircleShape)
) ) {
drawCircle(color = status.color)
Spacer(modifier = Modifier.height(8.dp)) }
}
if (room.unreadCount > 0) {
Badge(
containerColor = Color(0xFFDA7029), // 使用你的主橘色
contentColor = Color.White
) {
Text(
text = if (room.unreadCount > 99) "99+" else room.unreadCount.toString(),
modifier = Modifier.padding(horizontal = 4.dp)
)
} }
} }
} }
}
}
}
enum class UserStatus(val color: Color) {
ONLINE(Color.Green),
AWAY(Color.Yellow),
OFFLINE(Color.Gray),
UNKNOWN(Color.DarkGray);
companion object {
fun fromString(status: String?): UserStatus {
return when (status?.lowercase()) {
"online" -> ONLINE
"away" -> AWAY
"offline" -> OFFLINE
else -> UNKNOWN
}
} }
} }
} }