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 @@ -55,6 +55,8 @@ return dummyNodeForRobotextMessageHeightMeasurement( item.robotext, item.messageInfo.threadID, + item.threadCreatedFromMessage, + item.reactions, ); } invariant(false, 'NodeHeightMeasurer asked for dummy for non-text message'); 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,87 @@ import { useStyles } from '../themes/colors.js'; import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js'; +type DummyInlineEngagementNodeProps = { + ...React.ElementConfig, + +editedLabel?: ?string, + +sidebarInfo: ?ThreadInfo, + +reactions: ReactionInfo, +}; +function DummyInlineEngagementNode( + props: DummyInlineEngagementNodeProps, +): React.Node { + const { editedLabel, sidebarInfo, reactions, ...rest } = props; + + const dummyEditedLabel = React.useMemo(() => { + if (!editedLabel) { + return null; + } + + return ( + + + {editedLabel} + + + ); + }, [editedLabel]); + + const dummySidebarItem = React.useMemo(() => { + if (!sidebarInfo) { + return null; + } + + const repliesText = getInlineEngagementSidebarText(sidebarInfo); + return ( + + {repliesText} + + ); + }, [sidebarInfo]); + + const dummyReactionsList = React.useMemo(() => { + if (Object.keys(reactions).length === 0) { + return null; + } + + return Object.keys(reactions).map(reaction => { + const numOfReacts = reactions[reaction].users.length; + return ( + + {`${reaction} ${numOfReacts}`} + + ); + }); + }, [reactions]); + + const dummyContainerStyle = React.useMemo( + () => [unboundStyles.inlineEngagement, unboundStyles.dummyInlineEngagement], + [], + ); + + if (!dummyEditedLabel && !dummySidebarItem && !dummyReactionsList) { + return null; + } + + return ( + + {dummyEditedLabel} + {dummySidebarItem} + {dummyReactionsList} + + ); +} + type Props = { +messageInfo: MessageInfo, +threadInfo: ThreadInfo, @@ -61,28 +142,41 @@ const styles = useStyles(unboundStyles); + const editedLabelStyle = React.useMemo(() => { + const stylesResult = [styles.messageLabel, styles.messageLabelColor]; + if (isLeft) { + stylesResult.push(styles.messageLabelLeft); + } else { + stylesResult.push(styles.messageLabelRight); + } + + return stylesResult; + }, [ + isLeft, + styles.messageLabel, + styles.messageLabelColor, + styles.messageLabelLeft, + styles.messageLabelRight, + ]); + const editedLabel = React.useMemo(() => { if (!label) { return null; } - const labelLeftRight = isLeft - ? styles.messageLabelLeft - : styles.messageLabelRight; - return ( - {label} + {label} ); - }, [isLeft, label, styles]); + }, [editedLabelStyle, label]); const unreadStyle = sidebarThreadInfo?.currentUser.unread ? styles.unread : null; const repliesStyles = React.useMemo( - () => [styles.repliesText, unreadStyle], - [styles.repliesText, unreadStyle], + () => [styles.repliesText, styles.repliesTextColor, unreadStyle], + [styles.repliesText, styles.repliesTextColor, unreadStyle], ); const onPressSidebar = React.useCallback(() => { @@ -94,7 +188,7 @@ const repliesText = getInlineEngagementSidebarText(sidebarThreadInfo); const sidebarStyle = React.useMemo(() => { - const stylesResult = [styles.sidebar]; + const stylesResult = [styles.sidebar, styles.sidebarColor]; if (Object.keys(reactions).length === 0) { return stylesResult; @@ -111,6 +205,7 @@ isRight, reactions, styles.sidebar, + styles.sidebarColor, styles.sidebarMarginLeft, styles.sidebarMarginRight, ]); @@ -161,7 +256,10 @@ }, [navigate, reactions]); const reactionStyle = React.useMemo(() => { - const stylesResult = [styles.reactionsContainer]; + const stylesResult = [ + styles.reactionsContainer, + styles.reactionsContainerColor, + ]; if (isRight) { stylesResult.push(styles.reactionsContainerMarginLeft); @@ -173,6 +271,7 @@ }, [ isRight, styles.reactionsContainer, + styles.reactionsContainerColor, styles.reactionsContainerMarginLeft, styles.reactionsContainerMarginRight, ]); @@ -198,7 +297,9 @@ activeOpacity={0.7} key={reaction} > - {`${reaction} ${numOfReacts}`} + {`${reaction} ${numOfReacts}`} ); }); @@ -208,6 +309,7 @@ reactionStyle, reactions, styles.reaction, + styles.reactionColor, styles.reactionsContainerSelected, ]); @@ -244,6 +346,9 @@ flexWrap: 'wrap', top: inlineEngagementStyle.topOffset, }, + dummyInlineEngagement: { + marginRight: 8, + }, centerInlineEngagement: { marginLeft: 20, marginRight: 20, @@ -256,12 +361,20 @@ sidebar: { flexDirection: 'row', alignItems: 'center', - backgroundColor: 'inlineEngagementBackground', paddingHorizontal: 8, paddingVertical: 4, borderRadius: 8, marginTop: inlineEngagementStyle.marginTop, }, + dummySidebar: { + paddingRight: 8, + // 14 (icon) + 4 (marginRight of icon) + 8 (original left padding) + paddingLeft: 26, + marginRight: 4, + }, + sidebarColor: { + backgroundColor: 'inlineEngagementBackground', + }, sidebarMarginLeft: { marginLeft: 4, }, @@ -273,10 +386,12 @@ marginRight: 4, }, repliesText: { - color: 'inlineEngagementLabel', fontSize: 14, lineHeight: 22, }, + repliesTextColor: { + color: 'inlineEngagementLabel', + }, unread: { color: 'listForegroundLabel', fontWeight: 'bold', @@ -285,12 +400,17 @@ display: 'flex', flexDirection: 'row', alignItems: 'center', - backgroundColor: 'inlineEngagementBackground', paddingHorizontal: 8, paddingVertical: 4, borderRadius: 8, marginTop: inlineEngagementStyle.marginTop, }, + dummyReactionContainer: { + marginRight: 4, + }, + reactionsContainerColor: { + backgroundColor: 'inlineEngagementBackground', + }, reactionsContainerSelected: { borderWidth: 1, borderColor: 'inlineEngagementLabel', @@ -304,18 +424,26 @@ marginRight: 4, }, reaction: { - color: 'inlineEngagementLabel', fontSize: 14, lineHeight: 22, }, + reactionColor: { + color: 'inlineEngagementLabel', + }, messageLabel: { - color: 'messageLabel', paddingHorizontal: 3, fontSize: 13, top: inlineEngagementLabelStyle.topOffset, height: inlineEngagementLabelStyle.height, marginTop: inlineEngagementStyle.marginTop, }, + dummyMessageLabel: { + marginLeft: 9, + marginRight: 4, + }, + messageLabelColor: { + color: 'messageLabel', + }, messageLabelLeft: { marginLeft: 9, marginRight: 4, @@ -419,4 +547,4 @@ ); } -export { InlineEngagement, TooltipInlineEngagement }; +export { InlineEngagement, TooltipInlineEngagement, DummyInlineEngagementNode }; diff --git a/native/chat/inner-robotext-message.react.js b/native/chat/inner-robotext-message.react.js --- a/native/chat/inner-robotext-message.react.js +++ b/native/chat/inner-robotext-message.react.js @@ -4,7 +4,9 @@ import * as React from 'react'; import { Text, TouchableWithoutFeedback, View } from 'react-native'; +import type { ReactionInfo } from 'lib/selectors/chat-selectors.js'; import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; import { entityTextToReact, entityTextToRawString, @@ -12,6 +14,7 @@ type EntityText, } from 'lib/utils/entity-text.js'; +import { DummyInlineEngagementNode } from './inline-engagement.react.js'; import { useNavigateToThread } from './message-list-types.js'; import Markdown from '../markdown/markdown.react.js'; import { inlineMarkdownRules } from '../markdown/rules.react.js'; @@ -22,12 +25,20 @@ function dummyNodeForRobotextMessageHeightMeasurement( robotext: EntityText, threadID: string, + sidebarInfo: ?ThreadInfo, + reactions: ReactionInfo, ): React.Element { return ( - - - {entityTextToRawString(robotext, { threadID })} - + + + + {entityTextToRawString(robotext, { threadID })} + + + ); } diff --git a/native/chat/utils.js b/native/chat/utils.js --- a/native/chat/utils.js +++ b/native/chat/utils.js @@ -37,7 +37,6 @@ import type { ChatMessageInfoItemWithHeight, ChatMessageItemWithHeight, - ChatRobotextMessageInfoItemWithHeight, ChatTextMessageInfoItemWithHeight, } from '../types/chat-types.js'; import type { @@ -91,15 +90,6 @@ return height; } -function robotextMessageItemHeight( - item: ChatRobotextMessageInfoItemWithHeight, -): number { - if (item.threadCreatedFromMessage || Object.keys(item.reactions).length > 0) { - return item.contentHeight + inlineEngagementStyle.height; - } - return item.contentHeight; -} - function messageItemHeight(item: ChatMessageInfoItemWithHeight): number { let height = 0; if (item.messageShapeType === 'text') { @@ -107,7 +97,7 @@ } else if (item.messageShapeType === 'multimedia') { height += multimediaMessageItemHeight(item); } else { - height += robotextMessageItemHeight(item); + height += item.contentHeight; } if (item.startsConversation) { height += timestampHeight;