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 @@ -292,6 +292,7 @@ +threadCreatedFromMessage: ?ThreadInfo, +reactions: ReactionInfo, +hasBeenEdited: boolean, + +isPinned: boolean, }; export type ChatMessageItem = { itemType: 'loader' } | ChatMessageInfoItem; @@ -377,6 +378,24 @@ targetMessageEditMap.set(messageInfo.targetMessageID, messageInfo.text); } + 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--) { @@ -438,6 +457,11 @@ ? threadInfoFromSourceMessageID[messageInfo.id] : undefined; + const isPinned = !!( + originalMessageInfo.id && + targetMessagePinStatusMap.get(originalMessageInfo.id) + ); + const renderedReactions: ReactionInfo = (() => { const result = {}; @@ -496,6 +520,7 @@ threadCreatedFromMessage, reactions: renderedReactions, hasBeenEdited, + isPinned, }); } else { invariant(