fix(messaging): implement hydration pipeline to prevent history loss on page entry
Some checks failed
Frontend CI / build-and-push-web (push) Failing after 1m50s
Frontend CI / ota (android) (push) Successful in 2m8s
Frontend CI / ota (ios) (push) Successful in 2m47s
Frontend CI / build-android-apk (push) Successful in 45m48s

This addresses the issue where entering a chat page would only display recent
websocket messages, swallowing historical messages.

The fix implements a proper hydration pipeline in MessageSyncService that:
1. Tracks hydrated state per conversation via `hydratedConversations` Set
2. Unhydrated conversations run full pipeline: local contiguous range check,
   incremental sync above maxSeq, gap fill below minSeq, mark hydrated
3. Hydrated conversations only do lightweight incremental sync using trusted baseline
4. Clear conversation now also clears in-memory state and hydrated flag

Also adds:
- `getContiguousRange()` method to find local message continuity gaps
- `MESSAGES_PAGE_SIZE` (20) and `MAX_GAP_FILL_ROUNDS` (5) constants
- Test mocks with configurable state for hydration scenarios
- `messageHydration.test.ts` unit tests
This commit is contained in:
lafay
2026-06-28 14:15:36 +08:00
parent be77a9d04c
commit d8386b5f76
9 changed files with 795 additions and 74 deletions

View File

@@ -1515,7 +1515,10 @@ export const useChatScreen = (props?: ChatScreenProps) => {
try {
setHasMoreHistory(true);
await messageRepository.clearConversation(conversationId);
// 刷新消息列表
// 同步清空内存消息 + hydrated 标志,保证内存/DB/hydrated 三者一致。
// 否则 hydrated 残留会让 refreshMessages 走轻量增量同步,清空后仍显示旧消息。
useMessageStore.getState().clearMessages(conversationId);
// 刷新消息列表hydrated 已清,会重新走完整 hydration 管线)
await refreshMessages();
} catch (error) {
console.error('清空会话失败:', error);