dm-25
This commit is contained in:
parent
a4aeb6696f
commit
aefe861a44
2 changed files with 65 additions and 16 deletions
|
|
@ -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)
|
||||
|
|
@ -187,4 +212,20 @@ 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
|
||||
)
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue