This commit is contained in:
Eric85710 2026-05-26 14:58:46 +08:00
parent 57e546f733
commit 574a42dc33
3 changed files with 19 additions and 5 deletions

View file

@ -97,6 +97,9 @@ data class Message(
@Json(name = "is_edited") val isEdited: Boolean, @Json(name = "is_edited") val isEdited: Boolean,
@Json(name = "is_deleted") val isDeleted: Boolean, @Json(name = "is_deleted") val isDeleted: Boolean,
@Json(name = "reply_to_id") val replyToId: String? = null, @Json(name = "reply_to_id") val replyToId: String? = null,
@kotlin.jvm.Transient // 讓某些序列化工具忽略,Moshi 預設也會忽略沒有 @Json 的 var
var repliedMessage: Message? = null,
@Json(name = "forwarded_from_id") val forwardedFromId: String? = null, @Json(name = "forwarded_from_id") val forwardedFromId: String? = null,
@Json(name = "forwarded_from_room_id") val forwardedFromRoomId: String? = null, @Json(name = "forwarded_from_room_id") val forwardedFromRoomId: String? = null,
@Json(name = "attachment") val attachment: Attachment? = null, @Json(name = "attachment") val attachment: Attachment? = null,

View file

@ -47,18 +47,26 @@ class ChatRoomsRepository @Inject constructor(
if (response.isSuccessful) { if (response.isSuccessful) {
val body = response.body() val body = response.body()
if (body != null) { if (body != null) {
// 💡 核心邏輯:將訊息列表轉成 Map,方便用 ID 快速查找
val messageMap = body.messages.associateBy { it.id }
// 走訪每一條訊息,如果它有 replyToId,就去 Map 裡面找出那一條訊息塞給它
body.messages.forEach { message ->
if (!message.replyToId.isNullOrBlank()) {
message.repliedMessage = messageMap[message.replyToId]
}
}
Result.success(body) Result.success(body)
} else { } else {
// 如果後端 200 OK 但給空身體,這裏處理
Result.failure(Exception("回應身體為空 (Empty response body)")) Result.failure(Exception("回應身體為空 (Empty response body)"))
} }
} else { } else {
// 建議把後端的錯誤訊息也抓出來(如果後端有寫 error body 的話)
val errorMsg = response.errorBody()?.string() ?: "未知錯誤" val errorMsg = response.errorBody()?.string() ?: "未知錯誤"
Result.failure(Exception("網路請求失敗,錯誤碼: ${response.code()}, 訊息: $errorMsg")) Result.failure(Exception("網路請求失敗,錯誤碼: ${response.code()}, 訊息: $errorMsg"))
} }
} catch (e: Exception) { } catch (e: Exception) {
// 捕捉網路斷線 (IOException) 或解析失敗 (JsonDataException) 等狀況
Result.failure(e) Result.failure(e)
} }
} }

View file

@ -97,15 +97,18 @@ fun MessageMessaging(
} }
// ✨ 監聽發送狀態,如果失敗了就彈出提示並重置狀態 // ✨ 監聽發送狀態,如果失敗了就彈出提示並重置狀態
// 修改後的 LaunchedEffect
LaunchedEffect(sendStatus) { LaunchedEffect(sendStatus) {
if (sendStatus is SendMessageState.Error) { if (sendStatus is SendMessageState.Error) {
val errorMsg = (sendStatus as SendMessageState.Error).message val errorMsg = (sendStatus as SendMessageState.Error).message
Toast.makeText(context, "發送失敗: $errorMsg", Toast.LENGTH_SHORT).show() Toast.makeText(context, "發送失敗: $errorMsg", Toast.LENGTH_SHORT).show()
viewModel.resetSendMessageState() viewModel.resetSendMessageState()
} else if (sendStatus is SendMessageState.Success) { } else if (sendStatus is SendMessageState.Success) {
// ✨ 發送成功後,只重置狀態。讓 ViewModel 的 uiState 自動推播新訊息給 UI 即可! // 發送成功後,重置狀態以便下一次發送
viewModel.resetSendMessageState() viewModel.resetSendMessageState()
// 【優化體驗】:你可以在這裡重新呼叫 viewModel.loadMessages(roomId) 刷新列表
// 或者如果你的 ViewModel 已經會自動把新訊息塞進 uiState,這裡就什麼都不用做。
viewModel.loadMessages(roomId)
} }
} }