diff --git a/web/chat/composed-message.react.js b/web/chat/composed-message.react.js --- a/web/chat/composed-message.react.js +++ b/web/chat/composed-message.react.js @@ -1,7 +1,6 @@ // @flow import classNames from 'classnames'; -import invariant from 'invariant'; import * as React from 'react'; import { Circle as CircleIcon, @@ -20,7 +19,6 @@ import FailedSend from './failed-send.react'; import { InlineSidebar } from './inline-sidebar.react'; import MessageActionButtons from './message-action-buttons'; -import MessageReplyButton from './message-reply-button.react'; import { type OnMessagePositionWithContainerInfo, type MessagePositionInfo, @@ -120,34 +118,17 @@ ); } - let replyButton; + let messageActionButtons; if ( this.props.mouseOverMessagePosition && this.props.mouseOverMessagePosition.item.messageInfo.id === id && - this.props.canReply - ) { - const { inputState } = this.props; - invariant(inputState, 'inputState should be set in ComposedMessage'); - replyButton = ( - - ); - } - - let messageActionButton; - if ( - this.props.mouseOverMessagePosition && - this.props.mouseOverMessagePosition.item.messageInfo.id === id && - this.props.sidebarExistsOrCanBeCreated + (this.props.sidebarExistsOrCanBeCreated || this.props.canReply) ) { const availableTooltipPositions = isViewer ? availableTooltipPositionsForViewerMessage : availableTooltipPositionsForNonViewerMessage; - messageActionButton = ( + messageActionButtons = ( ); } - let viewerActionLinks, nonViewerActionLinks; - if (isViewer && (replyButton || messageActionButton)) { - viewerActionLinks = ( -
-
- {messageActionButton} - {replyButton} -
-
- ); - } else if (replyButton || messageActionButton) { - nonViewerActionLinks = ( -
+ let messageActionLinks; + if (messageActionButtons) { + const actionLinksClassName = classNames({ + [css.messageActionActiveArea]: true, + [css.viewerMessageActionActiveArea]: isViewer, + [css.nonViewerMessageActiveArea]: !isViewer, + }); + + messageActionLinks = ( +
- {replyButton} - {messageActionButton} + {messageActionButtons}
); } + const viewerActionLinks = isViewer ? messageActionLinks : null; + const nonViewerActionLinks = !isViewer ? messageActionLinks : null; + let inlineSidebar = null; if (item.threadCreatedFromMessage) { const positioning = isViewer ? 'right' : 'left'; diff --git a/web/chat/message-action-buttons.js b/web/chat/message-action-buttons.js --- a/web/chat/message-action-buttons.js +++ b/web/chat/message-action-buttons.js @@ -7,14 +7,18 @@ import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors'; import type { ThreadInfo } from 'lib/types/thread-types'; +import type { InputState } from '../input/input-state.js'; import { useOnClickThread, useOnClickPendingSidebar, } from '../selectors/nav-selectors'; import SWMansionIcon from '../SWMansionIcon.react'; import css from './message-action-buttons.css'; +import MessageReplyButton from './message-reply-button.react'; import type { ItemAndContainerPositionInfo, + MessagePositionInfo, + OnMessagePositionWithContainerInfo, PositionInfo, } from './position-types'; import { tooltipPositions, type TooltipPosition } from './tooltip-utils'; @@ -34,6 +38,13 @@ +item: ChatMessageInfoItem, +containerPosition: PositionInfo, +availableTooltipPositions: $ReadOnlyArray, + +setMouseOverMessagePosition?: ( + messagePositionInfo: MessagePositionInfo, + ) => void, + +mouseOverMessagePosition?: OnMessagePositionWithContainerInfo, + +canReply?: boolean, + +inputState?: ?InputState, + +sidebarExistsOrCanBeCreated?: boolean, }; function MessageActionButtons(props: MessageActionButtonsProps): React.Node { const { @@ -41,7 +52,13 @@ item, containerPosition, availableTooltipPositions, + setMouseOverMessagePosition, + mouseOverMessagePosition, + canReply, + inputState, + sidebarExistsOrCanBeCreated, } = props; + const [tooltipVisible, setTooltipVisible] = React.useState(false); const [pointingTo, setPointingTo] = React.useState(); @@ -98,6 +115,14 @@ [onPendingSidebarOpen, onThreadOpen, threadCreatedFromMessage], ); + const onReplyButtonClick = React.useCallback(() => { + invariant( + setMouseOverMessagePosition, + 'setMouseOverMessagePosition should be set if replyButton exists', + ); + setMouseOverMessagePosition({ type: 'off', item: item }); + }, [item, setMouseOverMessagePosition]); + const sidebarTooltipButtonText = threadCreatedFromMessage ? openSidebarText : createSidebarText; @@ -116,8 +141,25 @@ ); } - return ( -
+ let replyButton; + if (canReply) { + invariant(inputState, 'inputState must be set if replyButton exists'); + invariant( + mouseOverMessagePosition, + 'mouseOverMessagePosition must be set if replyButton exists', + ); + replyButton = ( + + ); + } + + let sidebarButton; + if (sidebarExistsOrCanBeCreated) { + sidebarButton = (
{tooltipMenu}
+ ); + } + + return ( +
+ {sidebarButton} + {replyButton}
); }