This commit is contained in:
Eric85710 2026-05-23 14:24:38 +08:00
parent a4aeb6696f
commit aefe861a44
2 changed files with 65 additions and 16 deletions

View file

@ -1,6 +1,7 @@
package com.example.login_v3.home.Message.UI.Detail
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@ -18,6 +19,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
@ -32,11 +34,15 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.login_v3.R
import com.example.login_v3.data.api.api_class.Message
import com.example.login_v3.home.Message.ViewModel.Detail.ChatViewModel
import com.example.login_v3.home.Message.ViewModel.Detail.MessagesUiState
@ -71,6 +77,15 @@ fun MessageMessaging(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
//avatar
if (uiState is MessagesUiState.Success) {
val successState = uiState as MessagesUiState.Success
UserAvatar(
avatarUrl = successState.partnerAvatarUrl,
modifier = Modifier.size(36.dp) // 適中的 TopBar 頭像大小
)
}
Text(text = topBarTitle)
// ✨ 如果是 Success 狀態,且對方是在線狀態(ONLINE),就顯示綠色小圓點
@ -88,14 +103,6 @@ fun MessageMessaging(
}
}
}
},
navigationIcon = {
IconButton(onClick = onBackClick) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "返回"
)
}
}
)
}
@ -115,8 +122,10 @@ fun MessageMessaging(
if (state.messages.isEmpty()) {
Text("目前沒有新訊息")
} else {
// ⚠️ 記得把原來的 state.messages 傳進去
MessageList(messages = state.messages)
MessageList(
messages = state.messages,
partnerAvatarUrl = state.partnerAvatarUrl
)
}
}
is MessagesUiState.Error -> {
@ -132,6 +141,7 @@ fun MessageMessaging(
@Composable
fun MessageList(
partnerAvatarUrl: Any?,
messages: List<Message>,
modifier: Modifier = Modifier
) {
@ -144,7 +154,11 @@ fun MessageList(
) {
items(messages) { message ->
val isMe = message.senderId == currentUserId
MessageRow(message = message, isMe = isMe)
MessageRow(
message = message,
partnerAvatarUrl = partnerAvatarUrl,
isMe = isMe
)
}
}
}
@ -152,12 +166,23 @@ fun MessageList(
@Composable
fun MessageRow(
message: Message,
isMe: Boolean
isMe: Boolean,
partnerAvatarUrl: Any?
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = if (isMe) Arrangement.End else Arrangement.Start
) {
// ✨ 如果是對方發的訊息,在對話框左邊顯示頭像
if (!isMe) {
UserAvatar(
avatarUrl = partnerAvatarUrl,
modifier = Modifier
.padding(end = 8.dp)
.size(32.dp) // 訊息旁的頭像稍微小一點
)
}
Box(
modifier = Modifier
.widthIn(max = 280.dp)
@ -188,3 +213,19 @@ fun MessageRow(
}
}
}
@Composable
fun UserAvatar(
avatarUrl: Any?, // ✨ 改成 Any?
modifier: Modifier = Modifier
) {
AsyncImage(
model = avatarUrl ?: R.drawable.avatar_v1, // 如果為 null,就用預設圖
contentDescription = "用戶頭像",
modifier = modifier
.background(Color.LightGray, shape = CircleShape)
.clip(CircleShape),
contentScale = ContentScale.Crop
)
}

View file

@ -4,11 +4,13 @@ package com.example.login_v3.home.Message.ViewModel.Detail
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.login_v3.R
import com.example.login_v3.data.repository.dm.ChatRoomsRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
import com.example.login_v3.data.api.api_class.Message
import com.example.login_v3.data.api.api_class.fullContactAvatarUrl
import com.example.login_v3.home.Message.ViewModel.UserStatus
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@ -20,8 +22,10 @@ sealed interface MessagesUiState {
data class Success(
val roomTitle: String,
val partnerStatus: UserStatus,
val partnerAvatarUrl: Any?,
val messages: List<Message>
) : MessagesUiState
data class Error(val message: String) : MessagesUiState
}
@ -46,18 +50,22 @@ class ChatViewModel @Inject constructor(
// 2. 根據房間資訊決定標題邏輯
val room = roomResult.getOrNull()
val (title, status) = if (room != null) {
// ✨ 這裡改用 Any? 來接收擴充屬性的結果
val (title, status, avatarUrl: Any?) = if (room != null) {
val name = room.partner?.displayName ?: room.partner?.username ?: "未知用戶"
val userStatus = UserStatus.fromString(room.partner?.status)
Pair(name, userStatus)
// 👇 直接呼叫你寫好的擴充屬性
val avatar = room.partner?.fullContactAvatarUrl
Triple(name, userStatus, avatar)
} else {
// 如果真的拿不到房間資訊,給個安全預設值
Pair("聊天室", UserStatus.UNKNOWN)
// 如果沒有房間資訊,就給預設的頭像資源
Triple("聊天室", UserStatus.UNKNOWN, R.drawable.avatar_v1)
}
_uiState.value = MessagesUiState.Success(
roomTitle = title,
partnerStatus = status,
partnerAvatarUrl = avatarUrl, // ✨ 這裡就會是完整的網址或 R.drawable.avatar_v1
messages = messagesResponse.messages
)