) => {
- if (threadCreatedFromMessage) {
- onThreadOpen(event);
- } else {
- onPendingSidebarOpen(event);
- }
- },
- [onPendingSidebarOpen, onThreadOpen, threadCreatedFromMessage],
- );
-
- const onReplyButtonClick = React.useCallback(() => {
- invariant(
- setMouseOverMessagePosition,
- 'setMouseOverMessagePosition should be set if replyButton exists',
- );
- setMouseOverMessagePosition({ type: 'off', item: item });
- }, [item, setMouseOverMessagePosition]);
-
- let tooltipText = '';
- if (activeTooltip === 'reply') {
- tooltipText = 'Reply';
- } else if (activeTooltip === 'sidebar') {
- tooltipText = threadCreatedFromMessage
- ? openSidebarText
- : createSidebarText;
- }
-
- let tooltipMenu = null;
- if (pointingTo && activeTooltip) {
- tooltipMenu = (
-
-
-
- );
- }
-
- let replyButton;
- if (canReply) {
- invariant(inputState, 'inputState must be set if replyButton exists');
- invariant(
- mouseOverMessagePosition,
- 'mouseOverMessagePosition must be set if replyButton exists',
- );
- replyButton = (
-
-
- {activeTooltip === 'reply' ? tooltipMenu : null}
-
- );
- }
-
- const sidebarExistsOrCanBeCreated = useSidebarExistsOrCanBeCreated(
- threadInfo,
- item,
- );
-
- let sidebarButton;
- if (sidebarExistsOrCanBeCreated) {
- sidebarButton = (
-
-
- {activeTooltip === 'sidebar' ? tooltipMenu : null}
-
- );
- }
-
- const { isViewer } = messageInfo.creator;
+ const { actions, messageTimestamp } = props;
+ const [activeTooltipLabel, setActiveTooltipLabel] = React.useState();
const messageActionButtonsContainerClassName = classNames({
[css.messageActionContainer]: true,
[css.messageActionButtons]: true,
- [css.messageActionButtonsViewer]: isViewer,
- [css.messageActionButtonsNonViewer]: !isViewer,
});
- return (
-
-
- {sidebarButton}
- {replyButton}
-
-
- );
-}
-function getIconPosition(
- rect: ClientRect,
- containerPosition: PositionInfo,
-): ItemAndContainerPositionInfo {
- const { top, bottom, left, right, width, height } = rect;
- return {
- containerPosition,
- itemPosition: {
- top:
- top - containerPosition.top + messageActionIconExcessVerticalWhitespace,
- bottom:
- bottom -
- containerPosition.top -
- messageActionIconExcessVerticalWhitespace,
- left: left - containerPosition.left,
- right: right - containerPosition.left,
- width,
- height: height - messageActionIconExcessVerticalWhitespace * 2,
- },
- };
-}
-
-function getMessageActionTooltipStyle(
- tooltipPosition: TooltipPosition,
-): TooltipStyle {
- let className;
- if (tooltipPosition === tooltipPositions.TOP_RIGHT) {
- className = classNames(
- css.messageActionTopRightTooltip,
- css.messageActionExtraAreaTop,
- css.messageActionExtraAreaTopRight,
- );
- } else if (tooltipPosition === tooltipPositions.TOP_LEFT) {
- className = classNames(
- css.messageActionTopLeftTooltip,
- css.messageActionExtraAreaTop,
- css.messageActionExtraAreaTopLeft,
+ const tooltipButtons = React.useMemo(() => {
+ if (!actions || actions.length === 0) {
+ return null;
+ }
+ const buttons = actions.map(({ label, onClick, actionButtonContent }) => {
+ const onMouseEnter = () => {
+ setActiveTooltipLabel(label);
+ };
+ const onMouseLeave = () =>
+ setActiveTooltipLabel(oldLabel =>
+ label === oldLabel ? null : oldLabel,
+ );
+
+ return (
+
+ {actionButtonContent}
+
+ );
+ });
+ return (
+ {buttons}
);
- } else if (tooltipPosition === tooltipPositions.RIGHT) {
- className = classNames(
- css.messageActionRightTooltip,
- css.messageActionExtraArea,
- css.messageActionExtraAreaRight,
- );
- } else if (tooltipPosition === tooltipPositions.LEFT) {
- className = classNames(
- css.messageActionLeftTooltip,
- css.messageActionExtraArea,
- css.messageActionExtraAreaLeft,
- );
- }
+ }, [actions, messageActionButtonsContainerClassName]);
+ const tooltipLabel = React.useMemo(() => {
+ if (!activeTooltipLabel) {
+ return null;
+ }
+ return {activeTooltipLabel}
;
+ }, [activeTooltipLabel]);
+
+ const tooltipTimestamp = React.useMemo(() => {
+ if (!messageTimestamp) {
+ return null;
+ }
+ return {messageTimestamp}
;
+ }, [messageTimestamp]);
- invariant(className, `${tooltipPosition} is not valid for message tooltip`);
- return { className };
+ return (
+
+
{tooltipLabel}
+ {tooltipButtons}
+ {tooltipTimestamp}
+
+ );
}
export default MessageTooltip;
diff --git a/web/chat/robotext-message.react.js b/web/chat/robotext-message.react.js
--- a/web/chat/robotext-message.react.js
+++ b/web/chat/robotext-message.react.js
@@ -24,6 +24,7 @@
import css from './robotext-message.css';
import { tooltipPositions } from './tooltip-utils';
+// eslint-disable-next-line no-unused-vars
const availableTooltipPositionsForRobotext = [
tooltipPositions.TOP_RIGHT,
tooltipPositions.RIGHT,
@@ -57,7 +58,7 @@
);
}
- const { item, threadInfo, sidebarExistsOrCanBeCreated } = this.props;
+ const { item, sidebarExistsOrCanBeCreated } = this.props;
const { id } = item.messageInfo;
let messageTooltip;
if (
@@ -65,14 +66,7 @@
this.props.mouseOverMessagePosition.item.messageInfo.id === id &&
sidebarExistsOrCanBeCreated
) {
- messageTooltip = (
-
- );
+ messageTooltip = ;
}
let messageTooltipLinks;
diff --git a/web/chat/tooltip-utils.js b/web/chat/tooltip-utils.js
--- a/web/chat/tooltip-utils.js
+++ b/web/chat/tooltip-utils.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant';
+import * as React from 'react';
import { calculateMaxTextWidth } from '../utils/text-utils';
import type { ItemAndContainerPositionInfo } from './position-types';
@@ -24,6 +25,12 @@
export type TooltipPosition = $Values;
+export type MessageTooltipAction = {
+ +label: string,
+ +onClick: (SyntheticEvent) => mixed,
+ +actionButtonContent: React.Node,
+};
+
const sizeOfTooltipArrow = 10; // 7px arrow + 3px extra
const tooltipMenuItemHeight = 22; // 17px line-height + 5px padding bottom
const tooltipInnerTopPadding = 5; // 5px bottom is included in last item