diff --git a/package/src/components/Message/Message.tsx b/package/src/components/Message/Message.tsx index ecbe268e3a..392bb3e808 100644 --- a/package/src/components/Message/Message.tsx +++ b/package/src/components/Message/Message.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import { GestureResponderEvent, StyleProp, + StyleSheet, useWindowDimensions, View, ViewStyle, @@ -323,14 +324,6 @@ const MessageWithContext = (props: MessagePropsWithContext) => { ); const isMessageTypeDeleted = message.type === 'deleted'; const { client } = chatContext; - const { - theme: { - colors: { bg_gradient_start }, - messageSimple: { targetedMessageContainer, unreadUnderlayColor = bg_gradient_start, wrapper }, - screenPadding, - semantics, - }, - } = useTheme(); const [rect, setRect] = useState<{ w: number; h: number; x: number; y: number } | undefined>( undefined, @@ -802,6 +795,11 @@ const MessageWithContext = (props: MessagePropsWithContext) => { } }, [overlayActive, message]); + const styles = useStyles({ + showUnreadUnderlay, + highlightedMessage: (isTargetedMessage || message.pinned) && !isMessageTypeDeleted, + }); + if (!(isMessageTypeDeleted || messageContentOrder.length)) { return null; } @@ -812,103 +810,82 @@ const MessageWithContext = (props: MessagePropsWithContext) => { return ( - - + + {overlayActive && rect ? ( + + ) : null} + {/*TODO: V9: Find a way to separate these in a dedicated file*/} + {overlayActive && rect ? ( { + const { width: w, height: h } = e.nativeEvent.layout; + + setOverlayTopH({ + h, + w, + x: isMyMessage ? screenW - rect.x - w : rect.x, + y: rect.y - h, + }); }} - /> + > + + ) : null} - {/*TODO: V9: Find a way to separate these in a dedicated file*/} - - {overlayActive && rect ? ( - { - const { width: w, height: h } = e.nativeEvent.layout; - - setOverlayTopH({ - h, - w, - x: isMyMessage ? screenW - rect.x - w : rect.x, - y: rect.y - h, - }); - }} - > - - - ) : null} - - + + + + {showMessageReactions ? ( + setShowMessageReactions(false)} + visible={showMessageReactions} + height={424} > - - - {showMessageReactions ? ( - setShowMessageReactions(false)} - visible={showMessageReactions} - height={424} + + + ) : null} + + {overlayActive && rect ? ( + { + const { width: w, height: h } = e.nativeEvent.layout; + setOverlayBottomH({ + h, + w, + x: isMyMessage ? screenW - rect.x - w : rect.x, + y: rect.y + rect.h, + }); + }} > - - - ) : null} - - {overlayActive && rect ? ( - { - const { width: w, height: h } = e.nativeEvent.layout; - setOverlayBottomH({ - h, - w, - x: isMyMessage ? screenW - rect.x - w : rect.x, - y: rect.y + rect.h, - }); - }} - > - - - ) : null} - - {isBounceDialogOpen ? ( - + ) : null} - + + {isBounceDialogOpen ? ( + + ) : null} ); @@ -1131,3 +1108,40 @@ export const Message = (props: MessageProps) => { /> ); }; + +const useStyles = ({ + showUnreadUnderlay, + highlightedMessage, +}: { + showUnreadUnderlay?: boolean; + highlightedMessage?: boolean; +}) => { + const { + theme: { + colors: { bg_gradient_start }, + messageSimple: { wrapper, unreadUnderlayColor = bg_gradient_start, targetedMessageContainer }, + screenPadding, + semantics, + }, + } = useTheme(); + return useMemo(() => { + return StyleSheet.create({ + wrapper: { + paddingHorizontal: screenPadding, + backgroundColor: showUnreadUnderlay ? unreadUnderlayColor : undefined, + ...(highlightedMessage + ? { backgroundColor: semantics.backgroundCoreHighlight, ...targetedMessageContainer } + : {}), + ...wrapper, + }, + }); + }, [ + wrapper, + screenPadding, + showUnreadUnderlay, + unreadUnderlayColor, + highlightedMessage, + semantics, + targetedMessageContainer, + ]); +}; diff --git a/package/src/components/Message/MessageSimple/MessageBubble.tsx b/package/src/components/Message/MessageSimple/MessageBubble.tsx index 7d9c18afbf..f772064431 100644 --- a/package/src/components/Message/MessageSimple/MessageBubble.tsx +++ b/package/src/components/Message/MessageSimple/MessageBubble.tsx @@ -55,36 +55,18 @@ export const MessageBubble = React.memo( MessageError, message, }: MessageBubbleProps) => { - const { - theme: { - messageSimple: { - bubble: { contentContainer, errorContainer, reactionListTopContainer, wrapper }, - }, - }, - } = useTheme(); + const styles = useStyles({ alignment }); const isMessageErrorType = message?.type === 'error' || message?.status === MessageStatusTypes.FAILED; return ( - + {reactionListPosition === 'top' && ReactionListTop ? ( - + ) : null} - + {isMessageErrorType ? ( - + ) : null} @@ -118,11 +100,7 @@ export const SwipableMessageBubble = React.memo( const { MessageSwipeContent, messageSwipeToReplyHitSlop, onSwipe, ...messageBubbleProps } = props; - const { - theme: { - messageSimple: { contentWrapper, swipeContentContainer }, - }, - } = useTheme(); + const styles = useStyles({ alignment: props.alignment }); const translateX = useSharedValue(0); const touchStart = useSharedValue<{ x: number; y: number } | null>(null); @@ -218,20 +196,13 @@ export const SwipableMessageBubble = React.memo( hitSlop={messageSwipeToReplyHitSlop} style={[ styles.contentWrapper, - contentWrapper, props.messageContentWidth > 0 && shouldRenderAnimatedWrapper ? { width: props.messageContentWidth } : {}, ]} > {shouldRenderAnimatedWrapper ? ( - + {MessageSwipeContent ? : null} ) : null} @@ -242,25 +213,55 @@ export const SwipableMessageBubble = React.memo( }, ); -const styles = StyleSheet.create({ - contentWrapper: { - alignItems: 'center', - flexDirection: 'row', - zIndex: 1, // To hide the stick inside the message content - }, - contentContainer: { - alignSelf: 'flex-start', - }, - swipeContentContainer: { - flexShrink: 0, - overflow: 'hidden', - position: 'relative', - }, - errorContainer: { - position: 'absolute', - top: 8, - right: -12, - }, - reactionListTopContainer: {}, - wrapper: {}, -}); +const useStyles = ({ alignment }: { alignment?: 'left' | 'right' }) => { + const { + theme: { + messageSimple: { + bubble: { contentContainer, errorContainer, reactionListTopContainer, wrapper }, + contentWrapper, + swipeContentContainer, + }, + }, + } = useTheme(); + return useMemo(() => { + return StyleSheet.create({ + contentWrapper: { + alignItems: 'center', + flexDirection: 'row', + zIndex: 1, // To hide the stick inside the message content + ...contentWrapper, + }, + contentContainer: { + alignSelf: alignment === 'left' ? 'flex-start' : 'flex-end', + ...contentContainer, + }, + swipeContentContainer: { + flexShrink: 0, + overflow: 'hidden', + position: 'relative', + ...swipeContentContainer, + }, + errorContainer: { + position: 'absolute', + top: 8, + right: -12, + ...errorContainer, + }, + reactionListTopContainer: { + alignSelf: alignment === 'left' ? 'flex-end' : 'flex-start', + ...reactionListTopContainer, + }, + wrapper: { + ...wrapper, + }, + }); + }, [ + alignment, + contentContainer, + contentWrapper, + errorContainer, + reactionListTopContainer, + swipeContentContainer, + wrapper, + ]); +}; diff --git a/package/src/components/Message/MessageSimple/MessageHeader.tsx b/package/src/components/Message/MessageSimple/MessageHeader.tsx index 2bddd14aad..0762b38c9f 100644 --- a/package/src/components/Message/MessageSimple/MessageHeader.tsx +++ b/package/src/components/Message/MessageSimple/MessageHeader.tsx @@ -1,6 +1,6 @@ -import React from 'react'; +import React, { useMemo } from 'react'; -import { View } from 'react-native'; +import { View, ViewStyle } from 'react-native'; import { MessageContextValue, @@ -12,7 +12,7 @@ import { } from '../../../contexts/messagesContext/MessagesContext'; import { useMessageReminder } from '../../../hooks/useMessageReminder'; -type MessageHeaderPropsWithContext = Pick & +type MessageHeaderPropsWithContext = Pick & Pick< MessagesContextValue, | 'MessagePinnedHeader' @@ -28,6 +28,7 @@ type MessageHeaderPropsWithContext = Pick & const MessageHeaderWithContext = (props: MessageHeaderPropsWithContext) => { const { + alignment, message, MessagePinnedHeader, shouldShowSavedForLaterHeader, @@ -39,8 +40,14 @@ const MessageHeaderWithContext = (props: MessageHeaderPropsWithContext) => { SentToChannelHeader, } = props; + const containerStyle: ViewStyle = useMemo(() => { + return { + alignItems: alignment === 'left' ? 'flex-start' : 'flex-end', + }; + }, [alignment]); + return ( - + {shouldShowReminderHeader && } {shouldShowSavedForLaterHeader && } {shouldShowPinnedHeader && } @@ -54,18 +61,25 @@ const areEqual = ( nextProps: MessageHeaderPropsWithContext, ) => { const { + alignment: prevAlignment, shouldShowSavedForLaterHeader: prevShouldShowSavedForLaterHeader, shouldShowPinnedHeader: prevShouldShowPinnedHeader, shouldShowReminderHeader: prevShouldShowReminderHeader, shouldShowSentToChannelHeader: prevShouldShowSentToChannelHeader, } = prevProps; const { + alignment: nextAlignment, shouldShowSavedForLaterHeader: nextShouldShowSavedForLaterHeader, shouldShowPinnedHeader: nextShouldShowPinnedHeader, shouldShowReminderHeader: nextShouldShowReminderHeader, shouldShowSentToChannelHeader: nextShouldShowSentToChannelHeader, } = nextProps; + const alignmentEqual = prevAlignment === nextAlignment; + if (!alignmentEqual) { + return false; + } + const shouldShowSavedForLaterHeaderEqual = prevShouldShowSavedForLaterHeader === nextShouldShowSavedForLaterHeader; if (!shouldShowSavedForLaterHeaderEqual) { @@ -100,7 +114,7 @@ const MemoizedMessageHeader = React.memo( export type MessageHeaderProps = Partial>; export const MessageHeader = (props: MessageHeaderProps) => { - const { message } = useMessageContext(); + const { alignment, message } = useMessageContext(); const { MessagePinnedHeader, MessageReminderHeader, @@ -125,6 +139,7 @@ export const MessageHeader = (props: MessageHeaderProps) => { return ( - - + + - - + - - - + /> + + + - + - - - - Message6 - + Message6 - + @@ -648,50 +621,50 @@ exports[`Thread should match thread snapshot 1`] = ` - + - + + - - Edited - - + Edited + - + @@ -728,285 +701,258 @@ exports[`Thread should match thread snapshot 1`] = ` ], { "backgroundColor": undefined, + "paddingHorizontal": 16, }, ] } + testID="message-wrapper" > - - + + - - + - - - + /> + + + - + - - - - Message5 - + Message5 - + @@ -1015,50 +961,50 @@ exports[`Thread should match thread snapshot 1`] = ` - + - + + - - Edited - - + Edited + - + @@ -1131,285 +1077,258 @@ exports[`Thread should match thread snapshot 1`] = ` ], { "backgroundColor": undefined, + "paddingHorizontal": 16, }, ] } + testID="message-wrapper" > - - + + - - + - - - + /> + + + - + - - - - Message4 - + Message4 - + @@ -1418,50 +1337,50 @@ exports[`Thread should match thread snapshot 1`] = ` - + - + + - - Edited - - + Edited + - + @@ -1499,286 +1418,259 @@ exports[`Thread should match thread snapshot 1`] = ` undefined, { "backgroundColor": undefined, + "paddingHorizontal": 16, }, ] } + testID="message-wrapper" > - - + + - - + - - - + /> + + + - + - - - - Message3 - + Message3 - + @@ -1787,50 +1679,50 @@ exports[`Thread should match thread snapshot 1`] = ` - + - + + - - Edited - - + Edited + - +