fix(16): improve attachment deduplication by attachmentId
The optimistic message uses 'attachment-{notation.id}' as ID while
REST API and WebSocket use the chat message ID. This caused duplicates
when fetchChatHistory ran after an optimistic upload.
Now deduplication checks both message ID and attachmentId for attachment
messages, preventing duplicates regardless of ID format.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
08283e24ef
commit
c1ed8470ae
|
|
@ -185,9 +185,18 @@ const sessionChatSlice = createSlice({
|
|||
state.messagesByChannel[channel] = [];
|
||||
}
|
||||
|
||||
// Deduplicate by msg_id
|
||||
const exists = state.messagesByChannel[channel].some(m => m.id === message.id);
|
||||
if (exists) return;
|
||||
// Deduplicate by msg_id and attachmentId (for attachment messages)
|
||||
const existsById = state.messagesByChannel[channel].some(m => m.id === message.id);
|
||||
if (existsById) return;
|
||||
|
||||
// For attachment messages, also check by attachmentId to avoid duplicates
|
||||
// from optimistic updates that use different ID format
|
||||
if (message.attachmentId) {
|
||||
const existsByAttachmentId = state.messagesByChannel[channel].some(
|
||||
m => m.attachmentId && m.attachmentId === message.attachmentId
|
||||
);
|
||||
if (existsByAttachmentId) return;
|
||||
}
|
||||
|
||||
// Add message
|
||||
state.messagesByChannel[channel].push(message);
|
||||
|
|
@ -335,9 +344,23 @@ const sessionChatSlice = createSlice({
|
|||
attachmentSize: null // Not available in REST API response (only in WebSocket)
|
||||
}));
|
||||
|
||||
// Deduplicate messages
|
||||
// Deduplicate messages by ID and by attachmentId (for attachment messages)
|
||||
// This handles the case where optimistic attachment message uses 'attachment-{id}' format
|
||||
// but the REST API returns the chat message ID
|
||||
const existingIds = new Set(state.messagesByChannel[channel].map(m => m.id));
|
||||
const newMessages = transformedMessages.filter(m => !existingIds.has(m.id));
|
||||
const existingAttachmentIds = new Set(
|
||||
state.messagesByChannel[channel]
|
||||
.filter(m => m.attachmentId)
|
||||
.map(m => m.attachmentId)
|
||||
);
|
||||
const newMessages = transformedMessages.filter(m => {
|
||||
// Check by message ID first
|
||||
if (existingIds.has(m.id)) return false;
|
||||
// For attachment messages, also check by attachmentId to avoid duplicates
|
||||
// from optimistic updates that use different ID format
|
||||
if (m.attachmentId && existingAttachmentIds.has(m.attachmentId)) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Prepend new messages (oldest first for pagination)
|
||||
state.messagesByChannel[channel] = [...newMessages, ...state.messagesByChannel[channel]];
|
||||
|
|
|
|||
Loading…
Reference in New Issue