fix(messages): stabilize conversation ordering by real message time
douyin-release-gate / verify (push) Failing after 18m44s

This commit is contained in:
2026-10-07 13:13:06 +08:00
parent 1ee5669027
commit d94f83cde9
6 changed files with 131 additions and 6 deletions
+18 -3
View File
@@ -32,16 +32,31 @@ function timestamp(value: string): number {
return Number.isFinite(time) ? time : 0;
}
function conversationTime(conversation: Conversation): number {
const time = Date.parse(conversation.last_message_at || '');
return Number.isFinite(time) ? time : Number.NEGATIVE_INFINITY;
}
export function mergeConversations(previous: Conversation[], incoming: Conversation[]): Conversation[] {
const merged = new Map(previous.map((conversation) => [conversationKey(conversation), conversation]));
const seen = new Set<string>();
for (const conversation of incoming) {
const key = conversationKey(conversation);
if (!seen.has(key)) merged.set(key, conversation);
const existing = merged.get(key);
const incomingTime = conversationTime(conversation);
const existingTime = existing ? conversationTime(existing) : Number.NEGATIVE_INFINITY;
// Late snapshots cannot roll back newer messages. For equal times, keep the
// first incoming page so overlapping later pages cannot replace its copy.
if (existing && (incomingTime < existingTime || (seen.has(key) && incomingTime === existingTime))) continue;
merged.set(key, conversation);
seen.add(key);
}
return [...merged.values()].sort((a, b) => timestamp(b.last_message_at) - timestamp(a.last_message_at)
|| conversationKey(a).localeCompare(conversationKey(b)));
return [...merged.values()].sort((a, b) => {
const aTime = conversationTime(a), bTime = conversationTime(b);
if (aTime !== bTime) return aTime > bTime ? -1 : 1;
if (a.account_id !== b.account_id) return a.account_id < b.account_id ? -1 : 1;
return a.peer_uid === b.peer_uid ? 0 : a.peer_uid < b.peer_uid ? -1 : 1;
});
}
export function mergeMessages(previous: PrivateMessage[], incoming: PrivateMessage[]): PrivateMessage[] {