Page MenuHomePhorge

D4912.1767184577.diff
No OneTemporary

Size
16 KB
Referenced Files
None
Subscribers
None

D4912.1767184577.diff

diff --git a/web/chat/chat-constants.js b/web/chat/chat-constants.js
new file mode 100644
--- /dev/null
+++ b/web/chat/chat-constants.js
@@ -0,0 +1,18 @@
+// @flow
+
+export const tooltipStyle = {
+ paddingLeft: 5,
+ paddingRight: 5,
+ rowGap: 3,
+};
+
+export const tooltipLabelStyle = {
+ padding: 6,
+ height: 20,
+};
+export const tooltipButtonStyle = {
+ paddingLeft: 6,
+ paddingRight: 6,
+ width: 30,
+ height: 38,
+};
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
@@ -124,31 +124,12 @@
this.props.mouseOverMessagePosition.item.messageInfo.id === id &&
(this.props.sidebarExistsOrCanBeCreated || this.props.canReply)
) {
+ // eslint-disable-next-line no-unused-vars
const availableTooltipPositions = isViewer
? availableTooltipPositionsForViewerMessage
: availableTooltipPositionsForNonViewerMessage;
- const messageTooltipProps = {
- threadInfo,
- item,
- availableTooltipPositions,
- mouseOverMessagePosition: this.props.mouseOverMessagePosition,
- };
-
- if (this.props.canReply) {
- messageTooltip = (
- <MessageTooltip
- {...messageTooltipProps}
- canReply={true}
- setMouseOverMessagePosition={this.props.setMouseOverMessagePosition}
- inputState={this.props.inputState}
- />
- );
- } else {
- messageTooltip = (
- <MessageTooltip {...messageTooltipProps} canReply={false} />
- );
- }
+ messageTooltip = <MessageTooltip messageTimestamp="" actions={[]} />;
}
let messageTooltipLinks;
diff --git a/web/chat/message-tooltip.css b/web/chat/message-tooltip.css
--- a/web/chat/message-tooltip.css
+++ b/web/chat/message-tooltip.css
@@ -1,9 +1,15 @@
+div.messageTooltipContainer {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ font-size: var(--s-font-14);
+}
+
div.messageActionContainer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
- padding: 0 6px;
background-color: var(--message-action-tooltip-bg);
border-radius: 8px;
width: fit-content;
@@ -17,66 +23,38 @@
padding: 10px 6px 6px;
color: var(--color-disabled);
}
+
div.messageActionButtons svg:hover {
cursor: pointer;
color: var(--fg);
}
-div.messageActionButtonsViewer {
- flex-direction: row;
- margin-left: auto;
- margin-right: 0;
-}
-div.messageActionButtonsNonViewer {
- flex-direction: row-reverse;
- margin-left: 0;
- margin-right: auto;
-}
-div.messageActionLinkIcon {
- margin: 0 3px;
- position: relative;
-}
-div.messageActionExtraAreaTop:before {
- height: 15px;
- width: 55px;
- content: '';
- position: absolute;
- bottom: -15px;
-}
-div.messageActionExtraAreaTopRight:before {
- right: 0;
-}
-div.messageActionExtraAreaTopLeft:before {
- left: 0;
-}
-div.messageActionExtraArea:before {
- height: 30px;
- width: 20px;
- content: '';
- position: absolute;
-}
-div.messageActionExtraAreaRight:before {
- left: -20px;
-}
-div.messageActionExtraAreaLeft:before {
- right: -20px;
+
+div.messageTooltipButton {
+ display: flex;
+ align-items: center;
+ justify-content: center;
}
-div.messageActionTopRightTooltip {
- bottom: 100%;
- margin-bottom: 1px;
- right: 0;
+
+div.messageTooltipLabel {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--message-action-tooltip-bg);
+ color: var(--tool-tip-color);
+ border-radius: 8px;
+ overflow: auto;
+ white-space: nowrap;
}
-div.messageActionTopLeftTooltip {
- bottom: 100%;
- margin-bottom: 1px;
- left: 0;
+
+div.leftTooltipAlign {
+ align-items: flex-start;
}
-div.messageActionLeftTooltip {
- top: 50%;
- right: 100%;
- margin-right: 7px;
+
+div.centerTooltipAlign {
+ align-items: center;
}
-div.messageActionRightTooltip {
- top: 50%;
- left: 100%;
- margin-left: 7px;
+
+div.rightTooltipAlign {
+ align-items: flex-end;
}
diff --git a/web/chat/message-tooltip.react.js b/web/chat/message-tooltip.react.js
--- a/web/chat/message-tooltip.react.js
+++ b/web/chat/message-tooltip.react.js
@@ -1,269 +1,115 @@
// @flow
import classNames from 'classnames';
-import invariant from 'invariant';
import * as React from 'react';
-import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { useSidebarExistsOrCanBeCreated } from 'lib/shared/thread-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-
-import CommIcon from '../CommIcon.react.js';
-import type { InputState } from '../input/input-state';
import {
- useOnClickThread,
- useOnClickPendingSidebar,
-} from '../selectors/nav-selectors';
-import MessageReplyButton from './message-reply-button.react';
+ tooltipButtonStyle,
+ tooltipLabelStyle,
+ tooltipStyle,
+} from './chat-constants';
import css from './message-tooltip.css';
-import type {
- ItemAndContainerPositionInfo,
- MessagePositionInfo,
- OnMessagePositionWithContainerInfo,
- PositionInfo,
-} from './position-types';
-import { tooltipPositions, type TooltipPosition } from './tooltip-utils';
-import {
- TooltipMenu,
- type TooltipStyle,
- TooltipTextItem,
-} from './tooltip.react';
-
-const messageActionIconExcessVerticalWhitespace = 10;
-
-const openSidebarText = 'Go to thread';
-const createSidebarText = 'Create thread';
-
-type TooltipType = 'sidebar' | 'reply';
+import { type MessageTooltipAction } from './tooltip-utils';
-type BaseMessageTooltipProps = {
- +threadInfo: ThreadInfo,
- +item: ChatMessageInfoItem,
- +availableTooltipPositions: $ReadOnlyArray<TooltipPosition>,
- +mouseOverMessagePosition: OnMessagePositionWithContainerInfo,
+type MessageTooltipProps = {
+ +actions: $ReadOnlyArray<MessageTooltipAction>,
+ +messageTimestamp: string,
+ +alignment?: 'left' | 'center' | 'right',
};
-type MessageTooltipProps =
- | {
- ...BaseMessageTooltipProps,
- +canReply: false,
- }
- | {
- ...BaseMessageTooltipProps,
- +canReply: true,
- +inputState: ?InputState,
- +setMouseOverMessagePosition: (
- messagePositionInfo: MessagePositionInfo,
- ) => void,
- };
function MessageTooltip(props: MessageTooltipProps): React.Node {
- const {
- threadInfo,
- item,
- availableTooltipPositions,
- mouseOverMessagePosition,
- canReply,
- } = props;
-
- const { containerPosition } = mouseOverMessagePosition;
-
- const [activeTooltip, setActiveTooltip] = React.useState<?TooltipType>();
- const [pointingTo, setPointingTo] = React.useState();
-
- const showTooltip = React.useCallback(
- (tooltipType: TooltipType, iconPosition: ItemAndContainerPositionInfo) => {
- if (activeTooltip) {
- return;
- }
- setActiveTooltip(tooltipType);
- setPointingTo(iconPosition);
- },
- [activeTooltip],
+ const { actions, messageTimestamp, alignment = 'left' } = props;
+ const [activeTooltipLabel, setActiveTooltipLabel] = React.useState<?string>();
+ const messageActionButtonsContainerClassName = classNames(
+ css.messageActionContainer,
+ css.messageActionButtons,
);
- const hideTooltip = React.useCallback(() => {
- setActiveTooltip(null);
- }, []);
+ const messageTooltipButtonStyle = React.useMemo(() => tooltipButtonStyle, []);
- const showSidebarTooltip = React.useCallback(
- (event: SyntheticEvent<HTMLDivElement>) => {
- const rect = event.currentTarget.getBoundingClientRect();
- const iconPosition = getIconPosition(rect, containerPosition);
- showTooltip('sidebar', iconPosition);
- },
- [containerPosition, showTooltip],
- );
-
- const showReplyTooltip = React.useCallback(
- (event: SyntheticEvent<HTMLDivElement>) => {
- const rect = event.currentTarget.getBoundingClientRect();
- const iconPosition = getIconPosition(rect, containerPosition);
- showTooltip('reply', iconPosition);
- },
- [containerPosition, showTooltip],
- );
-
- const { threadCreatedFromMessage, messageInfo } = item;
-
- const onThreadOpen = useOnClickThread(threadCreatedFromMessage);
- const onPendingSidebarOpen = useOnClickPendingSidebar(
- messageInfo,
- threadInfo,
- );
- const onSidebarButtonClick = React.useCallback(
- (event: SyntheticEvent<HTMLButtonElement>) => {
- if (threadCreatedFromMessage) {
- onThreadOpen(event);
- } else {
- onPendingSidebarOpen(event);
- }
- },
- [onPendingSidebarOpen, onThreadOpen, threadCreatedFromMessage],
- );
-
- const setMouseOverMessagePosition = props.canReply
- ? props.setMouseOverMessagePosition
- : null;
-
- const onReplyButtonClick = React.useCallback(() => {
- setMouseOverMessagePosition?.({
- type: 'off',
- item: item,
+ 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 (
+ <div
+ onMouseEnter={onMouseEnter}
+ onMouseLeave={onMouseLeave}
+ key={label}
+ onClick={onClick}
+ style={messageTooltipButtonStyle}
+ className={css.messageTooltipButton}
+ >
+ {actionButtonContent}
+ </div>
+ );
});
- }, [item, setMouseOverMessagePosition]);
-
- let tooltipText = '';
- if (activeTooltip === 'reply') {
- tooltipText = 'Reply';
- } else if (activeTooltip === 'sidebar') {
- tooltipText = threadCreatedFromMessage
- ? openSidebarText
- : createSidebarText;
- }
-
- let tooltipMenu = null;
- if (pointingTo && activeTooltip) {
- tooltipMenu = (
- <TooltipMenu
- availableTooltipPositions={availableTooltipPositions}
- targetPositionInfo={pointingTo}
- layoutPosition="relative"
- getStyle={getMessageActionTooltipStyle}
- >
- <TooltipTextItem text={tooltipText} />
- </TooltipMenu>
+ return (
+ <div className={messageActionButtonsContainerClassName}>{buttons}</div>
);
- }
+ }, [
+ actions,
+ messageActionButtonsContainerClassName,
+ messageTooltipButtonStyle,
+ ]);
+
+ const messageTooltipLabelStyle = React.useMemo(() => tooltipLabelStyle, []);
+ const messageTooltipTopLabelStyle = React.useMemo(
+ () => ({
+ height: `${tooltipLabelStyle.height + 2 * tooltipLabelStyle.padding}px`,
+ }),
+ [],
+ );
- let replyButton;
- if (canReply) {
- invariant(props.inputState, 'inputState must be set if replyButton exists');
- replyButton = (
- <div
- className={css.messageActionLinkIcon}
- onMouseEnter={showReplyTooltip}
- onMouseLeave={hideTooltip}
- >
- <MessageReplyButton
- messagePositionInfo={mouseOverMessagePosition}
- onReplyClick={onReplyButtonClick}
- inputState={props.inputState}
- />
- {activeTooltip === 'reply' ? tooltipMenu : null}
+ const tooltipLabel = React.useMemo(() => {
+ if (!activeTooltipLabel) {
+ return null;
+ }
+ return (
+ <div className={css.messageTooltipLabel} style={messageTooltipLabelStyle}>
+ {activeTooltipLabel}
</div>
);
- }
+ }, [activeTooltipLabel, messageTooltipLabelStyle]);
- const sidebarExistsOrCanBeCreated = useSidebarExistsOrCanBeCreated(
- threadInfo,
- item,
- );
-
- let sidebarButton;
- if (sidebarExistsOrCanBeCreated) {
- sidebarButton = (
- <div
- className={css.messageActionLinkIcon}
- onMouseEnter={showSidebarTooltip}
- onMouseLeave={hideTooltip}
- onClick={onSidebarButtonClick}
- >
- <CommIcon icon="sidebar-filled" size={16} />
- {activeTooltip === 'sidebar' ? tooltipMenu : null}
+ const tooltipTimestamp = React.useMemo(() => {
+ if (!messageTimestamp) {
+ return null;
+ }
+ return (
+ <div className={css.messageTooltipLabel} style={messageTooltipLabelStyle}>
+ {messageTimestamp}
</div>
);
- }
+ }, [messageTimestamp, messageTooltipLabelStyle]);
+
+ const messageTooltipContainerStyle = React.useMemo(() => tooltipStyle, []);
+
+ const containerClassNames = React.useMemo(
+ () =>
+ classNames(css.messageTooltipContainer, {
+ [css.leftTooltipAlign]: alignment === 'left',
+ [css.centerTooltipAlign]: alignment === 'center',
+ [css.rightTooltipAlign]: alignment === 'right',
+ }),
+ [alignment],
+ );
- const { isViewer } = messageInfo.creator;
- const messageActionButtonsContainerClassName = classNames({
- [css.messageActionContainer]: true,
- [css.messageActionButtons]: true,
- [css.messageActionButtonsViewer]: isViewer,
- [css.messageActionButtonsNonViewer]: !isViewer,
- });
return (
- <div>
- <div className={messageActionButtonsContainerClassName}>
- {sidebarButton}
- {replyButton}
- </div>
+ <div className={containerClassNames} style={messageTooltipContainerStyle}>
+ <div style={messageTooltipTopLabelStyle}>{tooltipLabel}</div>
+ {tooltipButtons}
+ {tooltipTimestamp}
</div>
);
}
-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,
- );
- } 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,
- );
- }
-
- invariant(className, `${tooltipPosition} is not valid for message tooltip`);
- return { className };
-}
-
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,15 +66,7 @@
this.props.mouseOverMessagePosition.item.messageInfo.id === id &&
sidebarExistsOrCanBeCreated
) {
- messageTooltip = (
- <MessageTooltip
- threadInfo={threadInfo}
- item={item}
- mouseOverMessagePosition={this.props.mouseOverMessagePosition}
- availableTooltipPositions={availableTooltipPositionsForRobotext}
- canReply={false}
- />
- );
+ messageTooltip = <MessageTooltip messageTimestamp="" actions={[]} />;
}
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<typeof tooltipPositions>;
+export type MessageTooltipAction = {
+ +label: string,
+ +onClick: (SyntheticEvent<HTMLDivElement>) => 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

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 31, 12:36 PM (2 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5873497
Default Alt Text
D4912.1767184577.diff (16 KB)

Event Timeline