diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js --- a/lib/reducers/message-reducer.js +++ b/lib/reducers/message-reducer.js @@ -1293,19 +1293,28 @@ let newThreads = threads; let newLocal = local; + // Store message IDs already contained within threads so that we + // do not insert duplicates + const displayedMessages = new Set(); + for (const threadID in threads) { + for (const msgID of threads[threadID].messageIDs) { + displayedMessages.add(msgID); + } + } + const threadIDsNeedResorting = new Set(); const actionPayloadMessages = translateClientDBMessageInfosToRawMessageInfos( action.payload, ); - const messageIDsToBeRemoved = []; + const messageIDsToBeRemoved = []; for (const id in actionPayloadMessages) { const message = actionPayloadMessages[id]; + const { threadID } = message; if ( (message.type === messageTypes.IMAGES || message.type === messageTypes.MULTIMEDIA) && !message.id ) { - const { threadID } = message; messageIDsToBeRemoved.push(id); newThreads = { ...newThreads, @@ -1319,9 +1328,24 @@ newLocal = _pickBy( (localInfo: LocalMessageInfo, key: string) => key !== id, )(newLocal); + } else if (!displayedMessages.has(id)) { + newThreads = { + ...newThreads, + [threadID]: { + ...newThreads[threadID], + messageIDs: [...newThreads[threadID].messageIDs, id], + }, + }; + threadIDsNeedResorting.add(threadID); } } + for (const threadID of threadIDsNeedResorting) { + newThreads[threadID].messageIDs = sortMessageIDs(actionPayloadMessages)( + newThreads[threadID].messageIDs, + ); + } + messageStore = { ...messageStore, messages: actionPayloadMessages,