dm-padding message-3

This commit is contained in:
eric 2026-07-07 17:37:51 +08:00
parent 50dc4dc528
commit 1fa6293bbb
2 changed files with 14 additions and 10 deletions

View file

@ -220,7 +220,6 @@ class ChatRoomsRepository @Inject constructor(
replyToId: String? = null replyToId: String? = null
): Result<Unit> { ): Result<Unit> {
val tempId = UUID.randomUUID().toString() val tempId = UUID.randomUUID().toString()
// 💡 配合你的 String 格式,產生 ISO 時間字串或乾淨的目前時間字串,例如 2026-06-07T05:26:48Z
val currentIsoTime = java.time.Instant.now().toString() val currentIsoTime = java.time.Instant.now().toString()
val tempMessageEntity = MessageEntity( val tempMessageEntity = MessageEntity(
@ -228,15 +227,16 @@ class ChatRoomsRepository @Inject constructor(
chatRoomId = roomId, chatRoomId = roomId,
senderId = currentUserId, senderId = currentUserId,
content = content, content = content,
type = "text", // 預設普通文字 type = "text",
createdAt = currentIsoTime, createdAt = currentIsoTime,
isEdited = false, isEdited = false,
isDeleted = false, isDeleted = false,
replyToId = replyToId, replyToId = replyToId,
status = MessageStatus.SENDING, status = MessageStatus.SENDING, // 👈 畫面立刻轉圈圈
reactions = emptyList() reactions = emptyList()
) )
// 1. 先塞入暫存假資料
messageDao.insertOrUpdate(tempMessageEntity) messageDao.insertOrUpdate(tempMessageEntity)
return try { return try {
@ -246,23 +246,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) {
// 成功:刪除假的,插入真的
messageDao.deleteById(tempId)
val successEntity = MessageEntity( val successEntity = MessageEntity(
id = body.id, id = body.id, // 後端給的正式 ID
chatRoomId = roomId, chatRoomId = roomId,
senderId = body.senderId, senderId = body.senderId,
content = body.content, content = body.content,
type = body.type, type = body.type,
createdAt = body.createdAt, // 後端確認的正式時間 createdAt = body.createdAt,
isEdited = body.isEdited, isEdited = body.isEdited,
isDeleted = body.isDeleted, isDeleted = body.isDeleted,
replyToId = body.replyToId, replyToId = body.replyToId,
status = MessageStatus.SUCCESS, status = MessageStatus.SUCCESS, // 👈 狀態轉為成功
reactions = body.reactions reactions = body.reactions
) )
messageDao.insertOrUpdate(successEntity)
// 🎯 2. 【關鍵大優化】利用剛寫好的 Transaction 一口氣替換!
// 這會讓 Room 在同一個事務內完成「刪除 tempId + 寫入 successEntity」
// UI 監聽的 Flow 只會被觸發一次,完美絕緣任何閃爍問題!
messageDao.replaceTempMessageWithSuccess(tempId, successEntity)
Result.success(Unit) Result.success(Unit)
} else { } else {
messageDao.insertOrUpdate(tempMessageEntity.copy(status = MessageStatus.FAILED)) messageDao.insertOrUpdate(tempMessageEntity.copy(status = MessageStatus.FAILED))
@ -273,6 +276,7 @@ class ChatRoomsRepository @Inject constructor(
Result.failure(Exception("API Error")) Result.failure(Exception("API Error"))
} }
} catch (e: Exception) { } catch (e: Exception) {
// 網路斷線或超時,直接把本地假資料狀態改成 FAILED,UI 就會立刻顯示驚嘆號
messageDao.insertOrUpdate(tempMessageEntity.copy(status = MessageStatus.FAILED)) messageDao.insertOrUpdate(tempMessageEntity.copy(status = MessageStatus.FAILED))
Result.failure(e) Result.failure(e)
} }

View file

@ -37,7 +37,7 @@ interface MessageDao {
@Query("SELECT * FROM messages WHERE id = :messageId LIMIT 1") @Query("SELECT * FROM messages WHERE id = :messageId LIMIT 1")
suspend fun getMessageById(messageId: String): MessageEntity? suspend fun getMessageById(messageId: String): MessageEntity?
// 3. 插入或更新單筆訊息 // 3. 插入或更新單筆訊息ssss
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertOrUpdate(message: MessageEntity) suspend fun insertOrUpdate(message: MessageEntity)