diff --git a/native/chat/chat-item-height-measurer.react.js b/native/chat/chat-item-height-measurer.react.js index b401f8579..3cf82f3bc 100644 --- a/native/chat/chat-item-height-measurer.react.js +++ b/native/chat/chat-item-height-measurer.react.js @@ -1,206 +1,212 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { getMessageLabel } from 'lib/shared/edit-messages-utils.js'; import { getInlineEngagementSidebarText, reactionsToRawString, } from 'lib/shared/inline-engagement-utils.js'; import { messageID } from 'lib/shared/message-utils.js'; import { messageTypes, type MessageType, } from 'lib/types/message-types-enum.js'; import { entityTextToRawString } from 'lib/utils/entity-text.js'; import type { MeasurementTask } from './chat-context-provider.react.js'; import { useComposedMessageMaxWidth } from './composed-message-width.js'; import { dummyNodeForRobotextMessageHeightMeasurement } from './inner-robotext-message.react.js'; import { dummyNodeForTextMessageHeightMeasurement } from './inner-text-message.react.js'; import type { NativeChatMessageItem } from './message-data.react.js'; import { MessageListContextProvider } from './message-list-types.js'; import { multimediaMessageContentSizes } from './multimedia-message-utils.js'; import { chatMessageItemKey } from './utils.js'; import NodeHeightMeasurer from '../components/node-height-measurer.react.js'; import { InputStateContext } from '../input/input-state.js'; type Props = { +measurement: MeasurementTask, }; const heightMeasurerKey = (item: NativeChatMessageItem) => { if (item.itemType !== 'message') { return null; } - const { messageInfo, threadCreatedFromMessage, reactions } = item; + const { messageInfo, hasBeenEdited, threadCreatedFromMessage, reactions } = + item; if (messageInfo.type === messageTypes.TEXT) { - return JSON.stringify({ text: messageInfo.text }); + return JSON.stringify({ + text: messageInfo.text, + edited: getMessageLabel(hasBeenEdited, messageInfo.threadID), + sidebar: getInlineEngagementSidebarText(threadCreatedFromMessage), + reactions: reactionsToRawString(reactions), + }); } else if (item.robotext) { const { threadID } = item.messageInfo; return JSON.stringify({ robotext: entityTextToRawString(item.robotext, { threadID }), sidebar: getInlineEngagementSidebarText(threadCreatedFromMessage), reactions: reactionsToRawString(reactions), }); } return null; }; // ESLint doesn't recognize that invariant always throws // eslint-disable-next-line consistent-return const heightMeasurerDummy = (item: NativeChatMessageItem) => { invariant( item.itemType === 'message', 'NodeHeightMeasurer asked for dummy for non-message item', ); const { messageInfo, hasBeenEdited } = item; if (messageInfo.type === messageTypes.TEXT) { const label = getMessageLabel(hasBeenEdited, messageInfo.threadID); return dummyNodeForTextMessageHeightMeasurement( messageInfo.text, label, item.threadCreatedFromMessage, item.reactions, ); } else if (item.robotext) { return dummyNodeForRobotextMessageHeightMeasurement( item.robotext, item.messageInfo.threadID, item.threadCreatedFromMessage, item.reactions, ); } invariant(false, 'NodeHeightMeasurer asked for dummy for non-text message'); }; function ChatItemHeightMeasurer(props: Props) { const composedMessageMaxWidth = useComposedMessageMaxWidth(); const inputState = React.useContext(InputStateContext); const inputStatePendingUploads = inputState?.pendingUploads; const { measurement } = props; const { threadInfo } = measurement; const heightMeasurerMergeItem = React.useCallback( (item: NativeChatMessageItem, height: ?number) => { if (item.itemType !== 'message') { return item; } const { messageInfo } = item; const messageType: MessageType = messageInfo.type; invariant( messageType !== messageTypes.SIDEBAR_SOURCE, 'Sidebar source messages should be replaced by sourceMessage before being measured', ); if ( messageInfo.type === messageTypes.IMAGES || messageInfo.type === messageTypes.MULTIMEDIA ) { // Conditional due to Flow... const localMessageInfo = item.localMessageInfo ? item.localMessageInfo : null; const id = messageID(messageInfo); const pendingUploads = inputStatePendingUploads?.[id]; const sizes = multimediaMessageContentSizes( messageInfo, composedMessageMaxWidth, ); return { itemType: 'message', messageShapeType: 'multimedia', messageInfo, localMessageInfo, threadInfo, startsConversation: item.startsConversation, startsCluster: item.startsCluster, endsCluster: item.endsCluster, threadCreatedFromMessage: item.threadCreatedFromMessage, pendingUploads, reactions: item.reactions, hasBeenEdited: item.hasBeenEdited, isPinned: item.isPinned, ...sizes, }; } invariant( height !== null && height !== undefined, 'height should be set', ); if (messageInfo.type === messageTypes.TEXT) { // Conditional due to Flow... const localMessageInfo = item.localMessageInfo ? item.localMessageInfo : null; return { itemType: 'message', messageShapeType: 'text', messageInfo, localMessageInfo, threadInfo, startsConversation: item.startsConversation, startsCluster: item.startsCluster, endsCluster: item.endsCluster, threadCreatedFromMessage: item.threadCreatedFromMessage, contentHeight: height, reactions: item.reactions, hasBeenEdited: item.hasBeenEdited, isPinned: item.isPinned, }; } invariant( item.messageInfoType !== 'composable', 'ChatItemHeightMeasurer was handed a messageInfoType=composable, but ' + `does not know how to handle MessageType ${messageInfo.type}`, ); invariant( item.messageInfoType === 'robotext', 'ChatItemHeightMeasurer was handed a messageInfoType that it does ' + `not recognize: ${item.messageInfoType}`, ); return { itemType: 'message', messageShapeType: 'robotext', messageInfo, threadInfo, startsConversation: item.startsConversation, startsCluster: item.startsCluster, endsCluster: item.endsCluster, threadCreatedFromMessage: item.threadCreatedFromMessage, robotext: item.robotext, contentHeight: height, reactions: item.reactions, }; }, [composedMessageMaxWidth, inputStatePendingUploads, threadInfo], ); return ( ); } const MemoizedChatItemHeightMeasurer: React.ComponentType = React.memo(ChatItemHeightMeasurer); export default MemoizedChatItemHeightMeasurer;