diff --git a/native/chat/chat-constants.js b/native/chat/chat-constants.js --- a/native/chat/chat-constants.js +++ b/native/chat/chat-constants.js @@ -6,7 +6,6 @@ }; export const inlineEngagementStyle = { - height: 38, marginTop: 5, marginBottom: 3, topOffset: -10, diff --git a/native/chat/chat-item-height-measurer.react.js b/native/chat/chat-item-height-measurer.react.js --- a/native/chat/chat-item-height-measurer.react.js +++ b/native/chat/chat-item-height-measurer.react.js @@ -17,6 +17,7 @@ import type { MeasurementTask } from './chat-context-provider.react.js'; import { useComposedMessageMaxWidth } from './composed-message-width.js'; +import { dummyNodeForInlineEngagementHeightMeasurement } from './inline-engagement.react.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'; @@ -51,6 +52,13 @@ sidebar: getInlineEngagementSidebarText(threadCreatedFromMessage), reactions: reactionsToRawString(reactions), }); + } else if (threadCreatedFromMessage || Object.keys(reactions).length > 0) { + // we enter this condition when the item is a multimedia message with an + // inline engagement + return JSON.stringify({ + sidebar: getInlineEngagementSidebarText(threadCreatedFromMessage), + reactions: reactionsToRawString(reactions), + }); } return null; }; @@ -62,24 +70,37 @@ item.itemType === 'message', 'NodeHeightMeasurer asked for dummy for non-message item', ); - const { messageInfo, hasBeenEdited } = item; + const { messageInfo, hasBeenEdited, threadCreatedFromMessage, reactions } = + item; + if (messageInfo.type === messageTypes.TEXT) { const label = getMessageLabel(hasBeenEdited, messageInfo.threadID); return dummyNodeForTextMessageHeightMeasurement( messageInfo.text, label, - item.threadCreatedFromMessage, - item.reactions, + threadCreatedFromMessage, + reactions, ); } else if (item.robotext) { return dummyNodeForRobotextMessageHeightMeasurement( item.robotext, - item.messageInfo.threadID, - item.threadCreatedFromMessage, - item.reactions, + messageInfo.threadID, + threadCreatedFromMessage, + reactions, + ); + } else if (threadCreatedFromMessage || Object.keys(reactions).length > 0) { + // we enter this condition when the item is a multimedia message with an + // inline engagement + + return dummyNodeForInlineEngagementHeightMeasurement( + threadCreatedFromMessage, + reactions, ); } - invariant(false, 'NodeHeightMeasurer asked for dummy for non-text message'); + invariant( + false, + 'NodeHeightMeasurer asked for dummy for multimedia message with no inline engagement', + ); }; function ChatItemHeightMeasurer(props: Props) { @@ -130,6 +151,7 @@ reactions: item.reactions, hasBeenEdited: item.hasBeenEdited, isPinned: item.isPinned, + inlineEngagementHeight: height, ...sizes, }; } diff --git a/native/chat/inline-engagement.react.js b/native/chat/inline-engagement.react.js --- a/native/chat/inline-engagement.react.js +++ b/native/chat/inline-engagement.react.js @@ -32,6 +32,20 @@ import { useStyles } from '../themes/colors.js'; import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js'; +function dummyNodeForInlineEngagementHeightMeasurement( + sidebarInfo: ?ThreadInfo, + reactions: ReactionInfo, +): React.Element { + return ( + + + + ); +} + type DummyInlineEngagementNodeProps = { ...React.ElementConfig, +editedLabel?: ?string, @@ -547,4 +561,9 @@ ); } -export { InlineEngagement, TooltipInlineEngagement, DummyInlineEngagementNode }; +export { + InlineEngagement, + TooltipInlineEngagement, + DummyInlineEngagementNode, + dummyNodeForInlineEngagementHeightMeasurement, +}; diff --git a/native/chat/multimedia-message-utils.js b/native/chat/multimedia-message-utils.js --- a/native/chat/multimedia-message-utils.js +++ b/native/chat/multimedia-message-utils.js @@ -6,7 +6,7 @@ import type { MediaInfo } from 'lib/types/media-types.js'; import type { MultimediaMessageInfo } from 'lib/types/message-types.js'; -import { inlineEngagementStyle, clusterEndHeight } from './chat-constants.js'; +import { clusterEndHeight } from './chat-constants.js'; import { failedSendHeight } from './failed-send.react.js'; import { authorNameHeight } from './message-header.react.js'; import type { @@ -104,10 +104,19 @@ function multimediaMessageItemHeight( item: ChatMultimediaMessageInfoItem, ): number { - const { messageInfo, contentHeight, startsCluster, endsCluster } = item; + const { + messageInfo, + contentHeight, + startsCluster, + endsCluster, + inlineEngagementHeight, + } = item; + const { creator } = messageInfo; const { isViewer } = creator; - let height = 5 + contentHeight; // 5 from marginBottom in ComposedMessage + + // 5 from marginBottom in ComposedMessage + let height = 5 + contentHeight; if (!isViewer && startsCluster) { height += authorNameHeight; } @@ -117,11 +126,8 @@ if (multimediaMessageSendFailed(item)) { height += failedSendHeight; } - if (item.threadCreatedFromMessage || Object.keys(item.reactions).length > 0) { - height += - inlineEngagementStyle.height + - inlineEngagementStyle.marginTop + - inlineEngagementStyle.marginBottom; + if (inlineEngagementHeight) { + height += inlineEngagementHeight; } return height; } diff --git a/native/types/chat-types.js b/native/types/chat-types.js --- a/native/types/chat-types.js +++ b/native/types/chat-types.js @@ -42,6 +42,9 @@ +isPinned: ?boolean, }; +// We "measure" the contentHeight of a multimedia message using the media +// dimensions. This means for multimedia messages we only need to actually +// measure the inline engagement node export type MultimediaContentSizes = { +imageHeight: number, +contentHeight: number, @@ -62,6 +65,7 @@ +reactions: ReactionInfo, +hasBeenEdited: ?boolean, +isPinned: ?boolean, + +inlineEngagementHeight: ?number, }; export type ChatMessageInfoItemWithHeight =