diff --git a/web/chat/message.react.js b/web/chat/message.react.js index 680f88161..c6e646ddd 100644 --- a/web/chat/message.react.js +++ b/web/chat/message.react.js @@ -1,67 +1,60 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors'; import { messageTypes } from 'lib/types/message-types'; import { type ThreadInfo } from 'lib/types/thread-types'; import { longAbsoluteDate } from 'lib/utils/date-utils'; import css from './chat-message-list.css'; import MultimediaMessage from './multimedia-message.react'; import { type OnMessagePositionWithContainerInfo, type MessagePositionInfo, } from './position-types'; import RobotextMessage from './robotext-message.react'; import TextMessage from './text-message.react'; type Props = { +item: ChatMessageInfoItem, +threadInfo: ThreadInfo, +setMouseOverMessagePosition: ( messagePositionInfo: MessagePositionInfo, ) => void, +mouseOverMessagePosition: ?OnMessagePositionWithContainerInfo, +timeZone: ?string, }; function Message(props: Props): React.Node { const { item, timeZone } = props; let conversationHeader = null; if (item.startsConversation) { conversationHeader = (
{longAbsoluteDate(item.messageInfo.time, timeZone)}
); } let message; if (item.messageInfo.type === messageTypes.TEXT) { message = ; } else if ( item.messageInfo.type === messageTypes.IMAGES || item.messageInfo.type === messageTypes.MULTIMEDIA ) { message = ; } else { invariant(item.robotext, "Flow can't handle our fancy types :("); - message = ( - - ); + message = ; } return (
{conversationHeader} {message}
); } export default Message; diff --git a/web/chat/robotext-message.react.js b/web/chat/robotext-message.react.js index e663cc244..c65520586 100644 --- a/web/chat/robotext-message.react.js +++ b/web/chat/robotext-message.react.js @@ -1,214 +1,166 @@ // @flow -import classNames from 'classnames'; import * as React from 'react'; import { useDispatch } from 'react-redux'; import { type RobotextChatMessageInfoItem } from 'lib/selectors/chat-selectors'; import { threadInfoSelector } from 'lib/selectors/thread-selectors'; import { splitRobotext, parseRobotextEntity } from 'lib/shared/message-utils'; -import { useSidebarExistsOrCanBeCreated } from 'lib/shared/thread-utils'; import type { Dispatch } from 'lib/types/redux-types'; import { type ThreadInfo } from 'lib/types/thread-types'; import Markdown from '../markdown/markdown.react'; import { linkRules } from '../markdown/rules.react'; import { updateNavInfoActionType } from '../redux/action-types'; import { useSelector } from '../redux/redux-utils'; import { InlineSidebar } from './inline-sidebar.react'; -import MessageTooltip from './message-tooltip.react'; -import type { - MessagePositionInfo, - OnMessagePositionWithContainerInfo, -} from './position-types'; import css from './robotext-message.css'; -import { tooltipPositions } from './tooltip-utils'; +import { tooltipPositions, useMessageTooltip } from './tooltip-utils'; -// eslint-disable-next-line no-unused-vars const availableTooltipPositionsForRobotext = [ - tooltipPositions.RIGHT_TOP, - tooltipPositions.RIGHT, tooltipPositions.LEFT, + tooltipPositions.LEFT_TOP, + tooltipPositions.LEFT_BOTTOM, + tooltipPositions.RIGHT, + tooltipPositions.RIGHT_TOP, + tooltipPositions.RIGHT_BOTTOM, ]; type BaseProps = { +item: RobotextChatMessageInfoItem, +threadInfo: ThreadInfo, - +setMouseOverMessagePosition: ( - messagePositionInfo: MessagePositionInfo, - ) => void, - +mouseOverMessagePosition: ?OnMessagePositionWithContainerInfo, }; type Props = { ...BaseProps, - // Redux state - +sidebarExistsOrCanBeCreated: boolean, + +onMouseLeave: ?() => mixed, + +onMouseEnter: (event: SyntheticEvent) => mixed, }; class RobotextMessage extends React.PureComponent { render() { let inlineSidebar; if (this.props.item.threadCreatedFromMessage) { inlineSidebar = (
); } - const { item, sidebarExistsOrCanBeCreated } = this.props; - const { id } = item.messageInfo; - let messageTooltip; - if ( - this.props.mouseOverMessagePosition && - this.props.mouseOverMessagePosition.item.messageInfo.id === id && - sidebarExistsOrCanBeCreated - ) { - messageTooltip = ; - } - - let messageTooltipLinks; - if (messageTooltip) { - messageTooltipLinks = ( -
- {messageTooltip} -
- ); - } - return (
{this.linkedRobotext()} - {messageTooltipLinks}
{inlineSidebar}
); } linkedRobotext() { const { item } = this.props; const { robotext } = item; const robotextParts = splitRobotext(robotext); const textParts = []; let keyIndex = 0; for (const splitPart of robotextParts) { if (splitPart === '') { continue; } if (splitPart.charAt(0) !== '<') { const key = `text${keyIndex++}`; textParts.push( {decodeURI(splitPart)} , ); continue; } const { rawText, entityType, id } = parseRobotextEntity(splitPart); if (entityType === 't' && id !== item.messageInfo.threadID) { textParts.push(); } else if (entityType === 'c') { textParts.push(); } else { textParts.push(rawText); } } return textParts; } - - onMouseEnter = (event: SyntheticEvent) => { - const { item } = this.props; - const rect = event.currentTarget.getBoundingClientRect(); - const { top, bottom, left, right, height, width } = rect; - const messagePosition = { top, bottom, left, right, height, width }; - this.props.setMouseOverMessagePosition({ - type: 'on', - item, - messagePosition, - }); - }; - - onMouseLeave = () => { - const { item } = this.props; - this.props.setMouseOverMessagePosition({ type: 'off', item }); - }; } - type BaseInnerThreadEntityProps = { +id: string, +name: string, }; type InnerThreadEntityProps = { ...BaseInnerThreadEntityProps, +threadInfo: ThreadInfo, +dispatch: Dispatch, }; class InnerThreadEntity extends React.PureComponent { render() { return {this.props.name}; } onClickThread = (event: SyntheticEvent) => { event.preventDefault(); const id = this.props.id; this.props.dispatch({ type: updateNavInfoActionType, payload: { activeChatThreadID: id, }, }); }; } const ThreadEntity = React.memo( function ConnectedInnerThreadEntity(props: BaseInnerThreadEntityProps) { const { id } = props; const threadInfo = useSelector(state => threadInfoSelector(state)[id]); const dispatch = useDispatch(); return ( ); }, ); function ColorEntity(props: { color: string }) { const colorStyle = { color: props.color }; return {props.color}; } const ConnectedRobotextMessage: React.ComponentType = React.memo( function ConnectedRobotextMessage(props) { - const sidebarExistsOrCanBeCreated = useSidebarExistsOrCanBeCreated( - props.threadInfo, - props.item, - ); + const { item, threadInfo } = props; + + const { onMouseLeave, onMouseEnter } = useMessageTooltip({ + item, + threadInfo, + availablePositions: availableTooltipPositionsForRobotext, + }); + return ( ); }, ); export default ConnectedRobotextMessage;