diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js --- a/lib/selectors/chat-selectors.js +++ b/lib/selectors/chat-selectors.js @@ -291,6 +291,7 @@ endsCluster: boolean, +threadCreatedFromMessage: ?ThreadInfo, +reactions: ReactionInfo, + +isPinned: boolean, }; export type ChatMessageItem = { itemType: 'loader' } | ChatMessageInfoItem; @@ -367,6 +368,24 @@ } } + const targetMessagePinStatusMap = new Map(); + // Once again, we iterate backwards to put the order of messages in + // chronological order (i.e. oldest to newest) to handle pinned messages. + // This is important because we want to make sure that the most recent pin + // action is the one that is used to determine whether a message + // is pinned or not. + for (let i = messages.length - 1; i >= 0; i--) { + const messageInfo = messages[i]; + if (messageInfo.type !== messageTypes.TOGGLE_PIN) { + continue; + } + + targetMessagePinStatusMap.set( + messageInfo.targetMessageID, + messageInfo.action === 'pin', + ); + } + const chatMessageItems = []; let lastMessageInfo = null; for (let i = messages.length - 1; i >= 0; i--) { @@ -410,6 +429,14 @@ ? threadInfoFromSourceMessageID[messageInfo.id] : undefined; + const isPinned = (() => { + let pinStatus; + if (originalMessageInfo.id) { + pinStatus = targetMessagePinStatusMap.get(originalMessageInfo.id); + } + return pinStatus === true; + })(); + const renderedReactions: ReactionInfo = (() => { const result = {}; @@ -467,6 +494,7 @@ endsCluster: false, threadCreatedFromMessage, reactions: renderedReactions, + isPinned, }); } else { invariant(