dm-padding message-7

This commit is contained in:
eric 2026-07-07 18:02:34 +08:00
parent 21a2e03830
commit ae88f96ad5
2 changed files with 25 additions and 24 deletions

View file

@ -175,7 +175,11 @@ class ChatRoomsRepository @Inject constructor(
//api get message and push to local //api get message and push to local
suspend fun refreshChatMessages(roomId: String, cursor: String? = null): Result<MessageResponse> { suspend fun refreshChatMessages(
roomId: String,
cursor: String? = null,
limit: Int? = null
): Result<MessageResponse> {
return try { return try {
// 1. 把 cursor 傳給 API // 1. 把 cursor 傳給 API
val response = api.getChatMessages(roomId, cursor = cursor) val response = api.getChatMessages(roomId, cursor = cursor)

View file

@ -121,7 +121,7 @@ class ChatViewModel @Inject constructor(
private var isLoadingMore = false // 防止重複戳 API private var isLoadingMore = false // 防止重複戳 API
// ===================================================================== // =====================================================================
// 💡 核心改造一:持續監聽本地資料庫的 Flow // 💡 核心改造一:持續監聽本地資料庫的 Flow (時序修正版)
// ===================================================================== // =====================================================================
fun loadMessages(roomId: String) { fun loadMessages(roomId: String) {
messageListenerJob?.cancel() messageListenerJob?.cancel()
@ -155,25 +155,26 @@ class ChatViewModel @Inject constructor(
Triple("聊天室", UserStatus.UNKNOWN, R.drawable.avatar_v1) Triple("聊天室", UserStatus.UNKNOWN, R.drawable.avatar_v1)
} }
// 持續監聽本地資料庫(即使載入更多老訊息,這裡也會自動感應並外發完整的 List) // 🎯 【關鍵優化】:先啟動資料庫 Flow 的監聽,確保任何寫入都不漏接
repository.getChatMessagesFlow(roomId).collect { localMessages -> launch {
_uiState.value = MessagesUiState.Success( repository.getChatMessagesFlow(roomId).collect { localMessages ->
roomTitle = title, _uiState.value = MessagesUiState.Success(
partnerStatus = status, roomTitle = title,
partnerAvatarUrl = avatarUrl, partnerStatus = status,
messages = localMessages, partnerAvatarUrl = avatarUrl,
currentUserId = currentLoggedInUserId messages = localMessages,
) currentUserId = currentLoggedInUserId
)
}
} }
}
// 🎯 修正:背景首刷,取得第一頁最新訊息,並記錄分頁標記 // 🎯 【關鍵優化】:確定開始監聽本地了,這時候才發起網路「首刷同步」
viewModelScope.launch { // 💡 加上 limit = 20 控制每頁數量
repository.refreshChatMessages(roomId, cursor = null) // 👈 傳入 null 代表抓最新 repository.refreshChatMessages(roomId, cursor = null, limit = 20)
.onSuccess { response -> .onSuccess { response ->
// 🌟 核心:記下這間聊天室第一頁的下一頁鑰匙
this@ChatViewModel.nextCursor = response.nextCursor this@ChatViewModel.nextCursor = response.nextCursor
this@ChatViewModel.hasMore = response.hasMore this@ChatViewModel.hasMore = response.hasMore
Log.d("ChatViewModel", "首刷成功,拿到第一頁 cursor: $nextCursor, hasMore: $hasMore")
repository.markAsRead(roomId).onFailure { error -> repository.markAsRead(roomId).onFailure { error ->
Log.e("ChatViewModel", "標記已讀失敗: ${error.message}") Log.e("ChatViewModel", "標記已讀失敗: ${error.message}")
@ -186,30 +187,26 @@ class ChatViewModel @Inject constructor(
} }
// ===================================================================== // =====================================================================
// 💡 核心新增:往上滑載入更多老訊息 // 💡 核心新增:往上滑載入更多老訊息 (補上 limit)
// ===================================================================== // =====================================================================
fun loadMoreMessages(roomId: String) { fun loadMoreMessages(roomId: String) {
// 1. 防禦性攔截:如果正在載入中、後端說沒更多了、或是鑰匙是空的,直接收工
if (isLoadingMore || !hasMore || nextCursor.isNullOrBlank()) return if (isLoadingMore || !hasMore || nextCursor.isNullOrBlank()) return
isLoadingMore = true isLoadingMore = true
Log.d("ChatViewModel", "觸發載入更多,當前 cursor: $nextCursor") Log.d("ChatViewModel", "觸發載入更多,當前 cursor: $nextCursor")
viewModelScope.launch { viewModelScope.launch {
// 2. 帶著目前最老的 nextCursor 去戳 Repository // 🎯 補上 limit = 20 傳遞給 Repository 與 API
repository.refreshChatMessages(roomId, cursor = nextCursor) repository.refreshChatMessages(roomId, cursor = nextCursor, limit = 20)
.onSuccess { response -> .onSuccess { response ->
// 3. 成功後,更新下一階段的分頁標記
this@ChatViewModel.nextCursor = response.nextCursor this@ChatViewModel.nextCursor = response.nextCursor
this@ChatViewModel.hasMore = response.hasMore this@ChatViewModel.hasMore = response.hasMore
Log.d("ChatViewModel", "載入更多成功,下一頁 cursor: $nextCursor, hasMore: $hasMore") Log.d("ChatViewModel", "載入更多成功,新 cursor: $nextCursor, hasMore: $hasMore")
} }
.onFailure { error -> .onFailure { error ->
Log.e("ChatViewModel", "載入更多老訊息失敗", error) Log.e("ChatViewModel", "載入更多老訊息失敗", error)
// 這裡可以選擇不處理,或者透過一個單發的事件(SharedFlow)通知 UI 彈 Toast
} }
// 4. 解鎖
isLoadingMore = false isLoadingMore = false
} }
} }