feat(message): implement incremental sync and atomic unread updates
Some checks failed
Frontend CI / ota-android (push) Successful in 1m38s
Frontend CI / ota-ios (push) Successful in 1m38s
Frontend CI / build-and-push-web (push) Successful in 4m28s
Frontend CI / build-android-apk (push) Has been cancelled

Refactor the messaging system to improve synchronization efficiency and state consistency.

- Implement incremental message synchronization using sequence numbers (seq) to reduce payload size.
- Add `markAllAsRead` batch API support to optimize read receipt processing.
- Introduce atomic state updates in `useMessageStore` to prevent inconsistent UI rendering during unread count changes.
- Implement notification deduplication in `WSMessageHandler` to prevent duplicate unread increments during reconnection.
- Optimize `MessageSyncService` to prioritize incremental sync over full snapshots when local data exists.
- Refactor `ReadReceiptManager` to use optimistic updates with proper rollback mechanisms.
- Fix minor UI issues in `SettingsScreen` and `PrivacySettingsScreen` related to theme picker z-index and style application.
This commit is contained in:
2026-05-12 18:04:32 +08:00
parent 7c7aaf9108
commit 48f31e6617
11 changed files with 280 additions and 159 deletions

View File

@@ -568,6 +568,19 @@ class MessageService {
});
}
/**
* 批量标记所有会话已读
* POST /api/v1/conversations/read-all
*/
async markAllAsRead(conversations: Array<{ id: string; lastSeq: number }>): Promise<void> {
await api.post('/conversations/read-all', {
conversations: conversations.map(c => ({
conversation_id: c.id,
last_read_seq: Number(c.lastSeq),
})),
});
}
/**
* 上报输入状态
* 优先使用WebSocket失败时降级到HTTP
@@ -597,6 +610,15 @@ class MessageService {
}
}
/**
* 获取同步元数据(轻量级 seq + 时间,用于增量同步判断)
* GET /api/v1/conversations/sync-data
*/
async getSyncData(): Promise<Array<{ id: string; max_seq: number; last_message_at: string }>> {
const response = await api.get<{ conversations: Array<{ id: string; max_seq: number; last_message_at: string }> }>('/conversations/sync-data');
return response.data?.conversations || [];
}
/**
* 获取单个会话未读数
* GET /api/v1/conversations/unread/count?conversation_id=xxx