This commit is contained in:
Eric85710 2026-05-18 15:46:41 +08:00
parent 8bbf1cfb27
commit 7f0047033a
3 changed files with 11 additions and 33 deletions

View file

@ -45,24 +45,16 @@ fun MessageMessaging(
onBackClick: () -> Unit, onBackClick: () -> Unit,
viewModel: ChatViewModel = hiltViewModel() viewModel: ChatViewModel = hiltViewModel()
) { ) {
// 加上 collectAsStateWithLifecycle() 轉換它
val uiState by viewModel.uiState.collectAsStateWithLifecycle() val uiState by viewModel.uiState.collectAsStateWithLifecycle()
LaunchedEffect(roomId) { LaunchedEffect(roomId) {
viewModel.loadMessages(roomId) viewModel.loadMessages(roomId)
Log.d("ChatDebug", "UI State 變更為: ${uiState::class.simpleName}")
} }
Scaffold( Scaffold(
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text("聊天室 ($roomId)") }, title = { Text("聊天室 ($roomId)") },
navigationIcon = {
IconButton(onClick = onBackClick) {
Text("<")
}
}
) )
} }
) { innerPadding -> ) { innerPadding ->
@ -96,7 +88,7 @@ fun MessageMessaging(
@Composable @Composable
fun MessageList( fun MessageList(
messages: List<Message>, // 這裡是正確的 Message messages: List<Message>,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val currentUserId = "user_123" val currentUserId = "user_123"
@ -106,7 +98,6 @@ fun MessageList(
contentPadding = PaddingValues(16.dp), contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
// items 內部拿到的 message 會依循 List<Message> 的型態
items(messages) { message -> items(messages) { message ->
val isMe = message.senderId == currentUserId val isMe = message.senderId == currentUserId
MessageRow(message = message, isMe = isMe) MessageRow(message = message, isMe = isMe)
@ -116,7 +107,7 @@ fun MessageList(
@Composable @Composable
fun MessageRow( fun MessageRow(
message: Message, // ✅ 修正這裡:將 Screen.Message 改為 Message message: Message,
isMe: Boolean isMe: Boolean
) { ) {
Row( Row(
@ -140,13 +131,13 @@ fun MessageRow(
Column { Column {
if (!isMe) { if (!isMe) {
Text( Text(
text = message.senderId, // ✅ 這樣型態對了,就能抓到欄位了! text = message.senderId,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = Color.Gray color = Color.Gray
) )
} }
Text( Text(
text = message.content, // ✅ 這樣型態對了,就能抓到欄位了! text = message.content,
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
} }

View file

@ -89,9 +89,8 @@ sealed class Screen(val route: String) {
object ScanQRcode : Screen("scan_QRcode") object ScanQRcode : Screen("scan_QRcode")
object MessageMessaging : Screen("message_messaging?roomId={roomId}") { object MessageMessaging : Screen("message_messaging?roomId={roomId}") {
fun createRoute(roomId: String): String { fun createRoute(roomId: String): String {
val encodedId = java.net.URLEncoder.encode(roomId, "UTF-8") // 🚀 修正:直接帶入原始 roomId,不進行 URL Encode
// 2. 修改這裡:帶入對應的格式 return "message_messaging?roomId=$roomId"
return "message_messaging?roomId=$encodedId"
} }
} }
} }
@ -139,23 +138,17 @@ fun Tg_Message(
//Message detail //Message detail
composable( composable(
route = Screen.MessageMessaging.route, // 現在是 "message_messaging?roomId={roomId}" route = Screen.MessageMessaging.route,
arguments = listOf( arguments = listOf(
navArgument("roomId") { navArgument("roomId") {
type = NavType.StringType type = NavType.StringType
nullable = true // 查詢參數建議改為允許為空 nullable = true
defaultValue = "" // 給予預設值 defaultValue = ""
} }
) )
) { backStackEntry -> ) { backStackEntry ->
// 這裡維持你寫好的安全解碼邏輯 // 🚀 修正:直接抓取 arguments 的字串,不再進行 URL Decode
val encodedRoomId = backStackEntry.arguments?.getString("roomId").orEmpty() val roomId = backStackEntry.arguments?.getString("roomId").orEmpty()
val roomId = try {
java.net.URLDecoder.decode(encodedRoomId, "UTF-8")
} catch (e: Exception) {
encodedRoomId
}
MessageMessaging( MessageMessaging(
roomId = roomId, roomId = roomId,

View file

@ -29,22 +29,16 @@ class ChatViewModel @Inject constructor(
val uiState: StateFlow<MessagesUiState> = _uiState.asStateFlow() val uiState: StateFlow<MessagesUiState> = _uiState.asStateFlow()
fun loadMessages(roomId: String) { fun loadMessages(roomId: String) {
// 🔴 Debug 1: 檢查傳進來的 roomId 是不是正確的,還是空的、被錯誤編碼的?
Log.d("ChatDebug", "ViewModel: loadMessages 開始執行, roomId = '$roomId'")
viewModelScope.launch { viewModelScope.launch {
_uiState.value = MessagesUiState.Loading _uiState.value = MessagesUiState.Loading
repository.getChatMessages(roomId) repository.getChatMessages(roomId)
.onSuccess { response -> .onSuccess { response ->
// 🔴 Debug 2: 檢查後端有沒有正確回傳,數量是多少?
Log.d("ChatDebug", "ViewModel: API 請求成功, 訊息數量 = ${response.messages.size}")
_uiState.value = MessagesUiState.Success(messages = response.messages) _uiState.value = MessagesUiState.Success(messages = response.messages)
} }
.onFailure { exception -> .onFailure { exception ->
// 🔴 Debug 3: 檢查是不是 API 報錯(例如 404, 500)或是解析 JSON 失敗
Log.e("ChatDebug", "ViewModel: API 請求失敗", exception)
_uiState.value = MessagesUiState.Error(message = exception.message ?: "未知錯誤") _uiState.value = MessagesUiState.Error(message = exception.message ?: "未知錯誤")
} }