diff --git a/package/src/components/Message/MessageSimple/utils/renderText.tsx b/package/src/components/Message/MessageSimple/utils/renderText.tsx index d424b56b89..e533655b62 100644 --- a/package/src/components/Message/MessageSimple/utils/renderText.tsx +++ b/package/src/components/Message/MessageSimple/utils/renderText.tsx @@ -198,11 +198,27 @@ export const renderText = < ); }; - const paragraphText: ReactNodeOutput = (node, output, { ...state }) => ( - - {output(node.content, state)} - - ); + const paragraphText: ReactNodeOutput = (node, output, { ...state }) => { + if (messageTextNumberOfLines !== undefined) { + // If we want to truncate the message text, lets only truncate the first paragraph + // and simply not render rest of the paragraphs. + if (state.key === '0' || state.key === 0) { + return ( + + {output(node.content, state)} + + ); + } else { + return null; + } + } + + return ( + + {output(node.content, state)} + + ); + }; const mentionedUsers = Array.isArray(mentioned_users) ? mentioned_users.reduce((acc, cur) => { diff --git a/package/src/components/MessageOverlay/MessageOverlay.tsx b/package/src/components/MessageOverlay/MessageOverlay.tsx index b305cb4314..74959463c9 100644 --- a/package/src/components/MessageOverlay/MessageOverlay.tsx +++ b/package/src/components/MessageOverlay/MessageOverlay.tsx @@ -3,6 +3,7 @@ import { Keyboard, Platform, SafeAreaView, StyleSheet, View, ViewStyle } from 'r import { PanGestureHandler, PanGestureHandlerGestureEvent, + ScrollView, State, TapGestureHandler, } from 'react-native-gesture-handler'; @@ -158,6 +159,7 @@ const MessageOverlayWithContext = < const wrapMessageInTheme = clientId === message?.user?.id && !!myMessageTheme; const [myMessageThemeString, setMyMessageThemeString] = useState(JSON.stringify(myMessageTheme)); + const [reactionListHeight, setReactionListHeight] = useState(0); useEffect(() => { if (myMessageTheme) { @@ -302,6 +304,200 @@ const MessageOverlayWithContext = < const { Attachment, FileAttachmentGroup, Gallery, MessageAvatar, Reply } = messagesContext || {}; + const renderContent = (messageTextNumberOfLines?: number) => ( + { + if (state === State.END) { + setOverlay('none'); + } + }} + > + + {message && ( + + {handleReaction && ownCapabilities?.sendReaction ? ( + reaction.type) || []} + setReactionListHeight={setReactionListHeight} + showScreen={showScreen} + /> + ) : null} + { + messageLayout.value = { + x: alignment === 'left' ? x + layoutWidth : x, + y, + }; + messageWidth.value = layoutWidth; + messageHeight.value = layoutHeight; + }} + style={[styles.alignEnd, styles.row, showScreenStyle]} + > + {alignment === 'left' && MessageAvatar && ( + + )} + + {messagesContext?.messageContentOrder?.map( + (messageContentType, messageContentOrderIndex) => { + switch (messageContentType) { + case 'quoted_reply': + return ( + message.quoted_message && + Reply && ( + + ['quotedMessage'] + } + styles={{ + messageContainer: { + maxWidth: vw(60), + }, + }} + /> + + ) + ); + case 'attachments': + return otherAttachments?.map( + (attachment, attachmentIndex) => + Attachment && ( + + ), + ); + case 'files': + return ( + FileAttachmentGroup && ( + + ) + ); + case 'gallery': + return ( + Gallery && ( + + ) + ); + case 'text': + default: + return otherAttachments?.length && otherAttachments[0].actions ? null : ( + + key={`message_text_container_${messageContentOrderIndex}`} + message={message} + messageOverlay + messageTextNumberOfLines={messageTextNumberOfLines} + onlyEmojis={onlyEmojis} + /> + ); + } + }, + )} + + + {messageActions && ( + + )} + {!!messageReactionTitle && + message.latest_reactions && + message.latest_reactions.length > 0 ? ( + ({ + alignment: clientId && clientId === reaction.user?.id ? 'right' : 'left', + id: reaction?.user?.id || '', + image: reaction?.user?.image, + name: reaction?.user?.name || reaction.user_id || '', + type: reaction.type, + })) as Reaction[] + } + showScreen={showScreen} + supportedReactions={messagesContext?.supportedReactions} + title={messageReactionTitle} + /> + ) : null} + + )} + + + ); + + // Scroll will only be enabled for message overlay when we show actions. + // When we show the reactions, we don't want to enable scroll since OverlayReactions component + // in itself is scrollable (FlatList). FlatList inside a ScrollView is not a good idea and results in error from RN. + const isScrollEnabled = !!messageActions && overlay === 'message'; + return ( @@ -319,198 +515,23 @@ const MessageOverlayWithContext = < > - { - if (state === State.END) { - setOverlay('none'); - } - }} - > - - {message && ( - - {handleReaction && ownCapabilities?.sendReaction ? ( - reaction.type) || [] - } - showScreen={showScreen} - /> - ) : null} - { - messageLayout.value = { - x: alignment === 'left' ? x + layoutWidth : x, - y, - }; - messageWidth.value = layoutWidth; - messageHeight.value = layoutHeight; - }} - style={[styles.alignEnd, styles.row, showScreenStyle]} - > - {alignment === 'left' && MessageAvatar && ( - - )} - - {messagesContext?.messageContentOrder?.map( - (messageContentType, messageContentOrderIndex) => { - switch (messageContentType) { - case 'quoted_reply': - return ( - message.quoted_message && - Reply && ( - - ['quotedMessage'] - } - styles={{ - messageContainer: { - maxWidth: vw(60), - }, - }} - /> - - ) - ); - case 'attachments': - return otherAttachments?.map( - (attachment, attachmentIndex) => - Attachment && ( - - ), - ); - case 'files': - return ( - FileAttachmentGroup && ( - - ) - ); - case 'gallery': - return ( - Gallery && ( - - ) - ); - case 'text': - default: - return otherAttachments?.length && - otherAttachments[0].actions ? null : ( - - key={`message_text_container_${messageContentOrderIndex}`} - message={message} - messageOverlay - messageTextNumberOfLines={messageTextNumberOfLines} - onlyEmojis={onlyEmojis} - /> - ); - } - }, - )} - - - {messageActions && ( - - )} - {!!messageReactionTitle && - message.latest_reactions && - message.latest_reactions.length > 0 ? ( - ({ - alignment: - clientId && clientId === reaction.user?.id ? 'right' : 'left', - id: reaction?.user?.id || '', - image: reaction?.user?.image, - name: reaction?.user?.name || reaction.user_id || '', - type: reaction.type, - })) as Reaction[] - } - showScreen={showScreen} - supportedReactions={messagesContext?.supportedReactions} - title={messageReactionTitle} - /> - ) : null} - - )} - - + {isScrollEnabled ? ( + + {renderContent()} + + ) : ( + renderContent(messageTextNumberOfLines) + )} diff --git a/package/src/components/MessageOverlay/OverlayReactionList.tsx b/package/src/components/MessageOverlay/OverlayReactionList.tsx index a78e5e0085..b3b8bb3321 100644 --- a/package/src/components/MessageOverlay/OverlayReactionList.tsx +++ b/package/src/components/MessageOverlay/OverlayReactionList.tsx @@ -239,6 +239,7 @@ export type OverlayReactionListPropsWithContext< y: number; }>; ownReactionTypes: string[]; + setReactionListHeight: React.Dispatch>; showScreen: Animated.SharedValue; fill?: FillProps['fill']; }; @@ -254,6 +255,7 @@ const OverlayReactionListWithContext = < handleReaction, messageLayout, ownReactionTypes, + setReactionListHeight, showScreen, setOverlay, supportedReactions = reactionData, @@ -354,6 +356,7 @@ const OverlayReactionListWithContext = < }) => { reactionListLayout.value = { height, width: layoutWidth }; reactionListHeight.value = height; + setReactionListHeight(height); }} style={[ styles.reactionList,