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,18 +1,9 @@ -div.container { - display: flex; - flex-direction: row; -} - -div.containerLeftAlign, -div.containerCenterAlign { - flex-direction: row-reverse; -} - div.messageTooltipContainer { display: flex; flex-direction: column; align-items: center; font-size: var(--s-font-14); + padding: 8px 0; } div.messageActionContainer { @@ -71,3 +62,7 @@ div.rightTooltipAlign { align-items: flex-end; } + +div.emojiKeyboard { + position: absolute; +} 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 @@ -15,15 +15,23 @@ tooltipStyle, } from './chat-constants.js'; import css from './message-tooltip.css'; -import { useSendReaction } from './reaction-message-utils.js'; +import { + useSendReaction, + getEmojiKeyboardPosition, +} from './reaction-message-utils.js'; import { useTooltipContext } from './tooltip-provider.js'; import { useSelector } from '../redux/redux-utils.js'; -import { type MessageTooltipAction } from '../utils/tooltip-utils.js'; +import type { + MessageTooltipAction, + TooltipSize, + TooltipPositionStyle, +} from '../utils/tooltip-utils.js'; type MessageTooltipProps = { +actions: $ReadOnlyArray, +messageTimestamp: string, - +alignment?: 'left' | 'center' | 'right', + +tooltipPositionStyle: TooltipPositionStyle, + +tooltipSize: TooltipSize, +item: ChatMessageInfoItem, +threadInfo: ThreadInfo, }; @@ -31,15 +39,35 @@ const { actions, messageTimestamp, - alignment = 'left', + tooltipPositionStyle, + tooltipSize, item, threadInfo, } = props; const { messageInfo, reactions } = item; + const { alignment = 'left' } = tooltipPositionStyle; + const [activeTooltipLabel, setActiveTooltipLabel] = React.useState(); - const { renderEmojiKeyboard } = useTooltipContext(); + const { shouldRenderEmojiKeyboard } = useTooltipContext(); + + const [emojiKeyboardPosition, setEmojiKeyboardPosition] = + React.useState(null); + + const emojiKeyboardRef = React.useCallback( + node => { + if (node) { + const position = getEmojiKeyboardPosition( + node, + tooltipPositionStyle, + tooltipSize, + ); + setEmojiKeyboardPosition(position); + } + }, + [tooltipPositionStyle, tooltipSize], + ); const messageActionButtonsContainerClassName = classNames( css.messageActionContainer, @@ -113,6 +141,17 @@ ); }, [messageTimestamp, messageTooltipLabelStyle]); + const emojiKeyboardPositionStyle = React.useMemo(() => { + if (!emojiKeyboardPosition) { + return null; + } + + return { + bottom: emojiKeyboardPosition.bottom, + left: emojiKeyboardPosition.left, + }; + }, [emojiKeyboardPosition]); + const nextLocalID = useSelector(state => state.nextLocalID); const localID = `${localIDPrefix}${nextLocalID}`; @@ -133,21 +172,29 @@ ); const emojiKeyboard = React.useMemo(() => { - if (!renderEmojiKeyboard) { + if (!shouldRenderEmojiKeyboard) { return null; } - return ; - }, [onEmojiSelect, renderEmojiKeyboard]); + + return ( +
+ +
+ ); + }, [ + emojiKeyboardPositionStyle, + emojiKeyboardRef, + onEmojiSelect, + shouldRenderEmojiKeyboard, + ]); const messageTooltipContainerStyle = React.useMemo(() => tooltipStyle, []); const containerClassName = classNames({ - [css.container]: true, - [css.containerLeftAlign]: alignment === 'left', - [css.containerCenterAlign]: alignment === 'center', - }); - - const messageTooltipContainerClassNames = classNames({ [css.messageTooltipContainer]: true, [css.leftTooltipAlign]: alignment === 'left', [css.centerTooltipAlign]: alignment === 'center', @@ -155,17 +202,14 @@ }); return ( -
+ <> {emojiKeyboard} -
+
{tooltipLabel}
{tooltipButtons} {tooltipTimestamp}
-
+ ); } diff --git a/web/chat/tooltip-provider.js b/web/chat/tooltip-provider.js --- a/web/chat/tooltip-provider.js +++ b/web/chat/tooltip-provider.js @@ -26,8 +26,8 @@ type TooltipContextType = { +renderTooltip: (params: RenderTooltipParams) => RenderTooltipResult, +clearTooltip: () => mixed, - +renderEmojiKeyboard: boolean, - +setRenderEmojiKeyboard: SetState, + +shouldRenderEmojiKeyboard: boolean, + +setShouldRenderEmojiKeyboard: SetState, }; const TooltipContext: React.Context = @@ -38,8 +38,8 @@ updateTooltip: () => {}, }), clearTooltip: () => {}, - renderEmojiKeyboard: false, - setRenderEmojiKeyboard: () => {}, + shouldRenderEmojiKeyboard: false, + setShouldRenderEmojiKeyboard: () => {}, }); type Props = { @@ -53,7 +53,7 @@ const [tooltipNode, setTooltipNode] = React.useState(null); const [tooltipPosition, setTooltipPosition] = React.useState(null); - const [renderEmojiKeyboard, setRenderEmojiKeyboard] = + const [shouldRenderEmojiKeyboard, setShouldRenderEmojiKeyboard] = React.useState(false); const clearTooltip = React.useCallback((tooltipToClose: symbol) => { @@ -63,7 +63,7 @@ tooltipCancelTimer.current = null; setTooltipNode(null); setTooltipPosition(null); - setRenderEmojiKeyboard(false); + setShouldRenderEmojiKeyboard(false); tooltipSymbol.current = null; }, []); @@ -156,10 +156,10 @@ () => ({ renderTooltip, clearTooltip: clearCurrentTooltip, - renderEmojiKeyboard, - setRenderEmojiKeyboard, + shouldRenderEmojiKeyboard, + setShouldRenderEmojiKeyboard, }), - [renderTooltip, clearCurrentTooltip, renderEmojiKeyboard], + [renderTooltip, clearCurrentTooltip, shouldRenderEmojiKeyboard], ); return ( diff --git a/web/utils/tooltip-utils.js b/web/utils/tooltip-utils.js --- a/web/utils/tooltip-utils.js +++ b/web/utils/tooltip-utils.js @@ -452,7 +452,7 @@ ): ?MessageTooltipAction { const { messageInfo } = item; - const { setRenderEmojiKeyboard } = useTooltipContext(); + const { setShouldRenderEmojiKeyboard } = useTooltipContext(); const canCreateReactionFromMessage = useCanCreateReactionFromMessage( threadInfo, @@ -467,10 +467,10 @@ const buttonContent = ; const onClickReact = () => { - if (!setRenderEmojiKeyboard) { + if (!setShouldRenderEmojiKeyboard) { return; } - setRenderEmojiKeyboard(true); + setShouldRenderEmojiKeyboard(true); }; return { @@ -478,7 +478,7 @@ onClick: onClickReact, label: 'React', }; - }, [canCreateReactionFromMessage, setRenderEmojiKeyboard]); + }, [canCreateReactionFromMessage, setShouldRenderEmojiKeyboard]); } function useMessageTooltipActions( @@ -548,13 +548,12 @@ tooltipSize, }); - const { alignment } = tooltipPositionStyle; - const tooltip = (