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 @@ -1,7 +1,26 @@ // @flow -export const inlineSidebarHeight = 20; -export const inlineSidebarMarginTop = 5; -export const inlineSidebarMarginBottom = 3; +export const composedMessageStyle = { + marginLeft: 12, + marginRight: 7, +}; + +export const inlineSidebarStyle = { + height: 38, + marginTop: 5, + marginBottom: 3, +}; +export const inlineSidebarLeftStyle = { + topOffset: -10, +}; + +export const inlineSidebarCenterStyle = { + topOffset: -5, +}; + +export const inlineSidebarRightStyle = { + marginRight: 22, + topOffset: -10, +}; export const clusterEndHeight = 7; diff --git a/native/chat/composed-message.react.js b/native/chat/composed-message.react.js --- a/native/chat/composed-message.react.js +++ b/native/chat/composed-message.react.js @@ -15,8 +15,10 @@ import { type AnimatedStyleObj, AnimatedView } from '../types/styles'; import { clusterEndHeight, - inlineSidebarMarginBottom, - inlineSidebarMarginTop, + inlineSidebarStyle, + inlineSidebarLeftStyle, + inlineSidebarRightStyle, + composedMessageStyle, } from './chat-constants'; import { useComposedMessageMaxWidth } from './composed-message-width'; import { FailedSend } from './failed-send.react'; @@ -138,12 +140,13 @@ let inlineSidebar = null; if (item.threadCreatedFromMessage) { const positioning = isViewer ? 'right' : 'left'; + const inlineSidebarPositionStyle = + positioning === 'left' + ? styles.leftInlineSidebar + : styles.rightInlineSidebar; inlineSidebar = ( - - + + ); } @@ -175,8 +178,8 @@ const styles = StyleSheet.create({ alignment: { - marginLeft: 12, - marginRight: 7, + marginLeft: composedMessageStyle.marginLeft, + marginRight: composedMessageStyle.marginRight, }, content: { alignItems: 'center', @@ -191,18 +194,29 @@ width: 16, }, inlineSidebar: { - marginBottom: inlineSidebarMarginBottom, - marginTop: inlineSidebarMarginTop, + marginBottom: inlineSidebarStyle.marginBottom, + marginTop: inlineSidebarStyle.marginTop, }, leftChatBubble: { justifyContent: 'flex-end', }, + leftInlineSidebar: { + justifyContent: 'flex-start', + position: 'relative', + top: inlineSidebarLeftStyle.topOffset, + }, messageBox: { marginRight: 5, }, rightChatBubble: { justifyContent: 'flex-start', }, + rightInlineSidebar: { + alignSelf: 'flex-end', + position: 'relative', + right: inlineSidebarRightStyle.marginRight, + top: inlineSidebarRightStyle.topOffset, + }, }); const ConnectedComposedMessage: React.ComponentType = React.memo( diff --git a/native/chat/inline-sidebar.react.js b/native/chat/inline-sidebar.react.js --- a/native/chat/inline-sidebar.react.js +++ b/native/chat/inline-sidebar.react.js @@ -2,69 +2,86 @@ import * as React from 'react'; import { Text, View } from 'react-native'; -import Icon from 'react-native-vector-icons/Feather'; import useInlineSidebarText from 'lib/hooks/inline-sidebar-text.react'; import type { ThreadInfo } from 'lib/types/thread-types'; -import Button from '../components/button.react'; +import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react'; +import SWMansionIcon from '../components/swmansion-icon.react'; import { useStyles } from '../themes/colors'; -import { inlineSidebarHeight } from './chat-constants'; +import { inlineSidebarStyle } from './chat-constants'; import { useNavigateToThread } from './message-list-types'; type Props = { - +threadInfo: ThreadInfo, - +positioning: 'left' | 'center' | 'right', + +threadInfo: ?ThreadInfo, + +reactions?: $ReadOnlyArray, + +disabled?: boolean, }; function InlineSidebar(props: Props): React.Node { - const { threadInfo } = props; - const { sendersText, repliesText } = useInlineSidebarText(threadInfo); + const { disabled = false, reactions, threadInfo } = props; + const { repliesText } = useInlineSidebarText(threadInfo); const navigateToThread = useNavigateToThread(); const onPress = React.useCallback(() => { - navigateToThread({ threadInfo }); - }, [navigateToThread, threadInfo]); + if (threadInfo && !disabled) { + navigateToThread({ threadInfo }); + } + }, [disabled, navigateToThread, threadInfo]); const styles = useStyles(unboundStyles); - let viewerIcon, nonViewerIcon, alignStyle; - if (props.positioning === 'right') { - viewerIcon = ; - alignStyle = styles.rightAlign; - } else if (props.positioning === 'left') { - nonViewerIcon = ( - - ); - alignStyle = styles.leftAlign; - } else { - nonViewerIcon = ( - - ); - alignStyle = styles.centerAlign; - } - const unreadStyle = threadInfo.currentUser.unread ? styles.unread : null; + const reactionList = React.useMemo(() => { + if (!reactions || reactions.length === 0) { + return null; + } + const reactionItems = reactions.map((reaction, idx) => { + return ( + + {reaction} + + ); + }); + return {reactionItems}; + }, [reactions, styles.reaction, styles.reactionsContainer]); + const unreadStyle = threadInfo?.currentUser.unread ? styles.unread : null; + const marginRight = reactionList ? styles.repliesMarginRight : null; + const repliesStyles = React.useMemo( + () => [marginRight, styles.repliesText, unreadStyle], + [marginRight, styles.repliesText, unreadStyle], + ); + const sidebarInfo = React.useMemo(() => { + if (!threadInfo) { + return null; + } + return ( + <> + + {repliesText} + + ); + }, [repliesStyles, repliesText, styles.icon, threadInfo]); return ( - - + + + {sidebarInfo} + {reactionList} + ); } const unboundStyles = { - content: { + container: { flexDirection: 'row', - marginRight: 30, - marginLeft: 10, - flex: 1, - height: inlineSidebarHeight, + height: inlineSidebarStyle.height, + display: 'flex', + backgroundColor: 'listBackground', + borderRadius: 16, }, unread: { color: 'listForegroundLabel', @@ -74,25 +91,32 @@ flexDirection: 'row', display: 'flex', alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'inlineSidebarBackground', + padding: 8, + borderRadius: 16, + height: inlineSidebarStyle.height, }, icon: { - color: 'listForegroundTertiaryLabel', + color: 'inlineSidebarLabel', + marginRight: 4, }, - name: { - paddingTop: 1, - color: 'listForegroundTertiaryLabel', - fontSize: 16, - paddingLeft: 4, - paddingRight: 2, + repliesText: { + color: 'inlineSidebarLabel', + fontSize: 14, + lineHeight: 22, }, - leftAlign: { - justifyContent: 'flex-start', + repliesMarginRight: { + marginRight: 12, }, - rightAlign: { - justifyContent: 'flex-end', + reaction: { + marginLeft: 4, + color: 'inlineSidebarLabel', }, - centerAlign: { - justifyContent: 'center', + reactionsContainer: { + display: 'flex', + flexDirection: 'row', + marginLeft: -4, }, }; 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 @@ -10,12 +10,7 @@ ChatMultimediaMessageInfoItem, MultimediaContentSizes, } from '../types/chat-types'; -import { - inlineSidebarMarginBottom, - inlineSidebarMarginTop, - inlineSidebarHeight, - clusterEndHeight, -} from './chat-constants'; +import { inlineSidebarStyle, clusterEndHeight } from './chat-constants'; import { failedSendHeight } from './failed-send.react'; import { authorNameHeight } from './message-header.react'; @@ -124,7 +119,9 @@ } if (item.threadCreatedFromMessage) { height += - inlineSidebarHeight + inlineSidebarMarginTop + inlineSidebarMarginBottom; + inlineSidebarStyle.height + + inlineSidebarStyle.marginTop + + inlineSidebarStyle.marginBottom; } return height; } diff --git a/native/chat/robotext-message.react.js b/native/chat/robotext-message.react.js --- a/native/chat/robotext-message.react.js +++ b/native/chat/robotext-message.react.js @@ -15,6 +15,7 @@ import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types'; import type { VerticalBounds } from '../types/layout-types'; import { AnimatedView } from '../types/styles'; +import { inlineSidebarCenterStyle } from './chat-constants'; import type { ChatNavigationProp } from './chat.react'; import InlineSidebar from './inline-sidebar.react'; import { InnerRobotextMessage } from './inner-robotext-message.react'; @@ -54,10 +55,7 @@ if (item.threadCreatedFromMessage) { inlineSidebar = ( - + ); } @@ -191,8 +189,9 @@ const unboundStyles = { sidebar: { - marginTop: -5, - marginBottom: 5, + marginTop: inlineSidebarCenterStyle.topOffset, + marginBottom: -inlineSidebarCenterStyle.topOffset, + alignSelf: 'center', }, }; diff --git a/native/chat/utils.js b/native/chat/utils.js --- a/native/chat/utils.js +++ b/native/chat/utils.js @@ -26,12 +26,7 @@ } from '../types/chat-types'; import type { LayoutCoordinates, VerticalBounds } from '../types/layout-types'; import type { AnimatedViewStyle } from '../types/styles'; -import { - clusterEndHeight, - inlineSidebarHeight, - inlineSidebarMarginBottom, - inlineSidebarMarginTop, -} from './chat-constants'; +import { clusterEndHeight, inlineSidebarStyle } from './chat-constants'; import { ChatContext, useHeightMeasurer } from './chat-context'; import { failedSendHeight } from './failed-send.react'; import { authorNameHeight } from './message-header.react'; @@ -71,7 +66,9 @@ } if (item.threadCreatedFromMessage) { height += - inlineSidebarHeight + inlineSidebarMarginTop + inlineSidebarMarginBottom; + inlineSidebarStyle.height + + inlineSidebarStyle.marginTop + + inlineSidebarStyle.marginBottom; } return height; } @@ -80,7 +77,7 @@ item: ChatRobotextMessageInfoItemWithHeight, ): number { if (item.threadCreatedFromMessage) { - return item.contentHeight + inlineSidebarHeight; + return item.contentHeight + inlineSidebarStyle.height; } return item.contentHeight; } diff --git a/native/themes/colors.js b/native/themes/colors.js --- a/native/themes/colors.js +++ b/native/themes/colors.js @@ -21,6 +21,8 @@ greenButton: '#6EC472', greenText: 'green', headerChevron: '#0A0A0A', + inlineSidebarBackground: '#E0E0E0', + inlineSidebarLabel: '#000000', link: '#036AFF', listBackground: 'white', listBackgroundLabel: 'black', @@ -90,6 +92,8 @@ greenButton: '#43A047', greenText: '#44FF44', headerChevron: '#FFFFFF', + inlineSidebarBackground: '#666666', + inlineSidebarLabel: '#FFFFFF', link: '#129AFF', listBackground: '#0A0A0A', listBackgroundLabel: '#C7C7CC',