diff --git a/web/chat/reaction-pill.react.js b/web/chat/reaction-pill.react.js --- a/web/chat/reaction-pill.react.js +++ b/web/chat/reaction-pill.react.js @@ -10,6 +10,13 @@ import { useSendReaction } from './reaction-message-utils.js'; import css from './reaction-pill.css'; +import { useReactionTooltip } from '../utils/tooltip-action-utils.js'; +import { tooltipPositions } from '../utils/tooltip-utils.js'; + +const availableReactionTooltipPositions = [ + tooltipPositions.TOP, + tooltipPositions.BOTTOM, +]; type Props = { +reaction: string, @@ -37,6 +44,12 @@ [reaction, sendReaction], ); + const { onMouseEnter, onMouseLeave } = useReactionTooltip({ + reaction, + reactions, + availablePositions: availableReactionTooltipPositions, + }); + const reactionInfo = reactions[reaction]; const numOfReacts = reactionInfo.users.length; @@ -46,7 +59,13 @@ }); return ( - + {`${reaction} ${numOfReacts}`} ); diff --git a/web/utils/tooltip-action-utils.js b/web/utils/tooltip-action-utils.js --- a/web/utils/tooltip-action-utils.js +++ b/web/utils/tooltip-action-utils.js @@ -5,7 +5,10 @@ import { useModalContext } from 'lib/components/modal-provider.react.js'; import { useResettingState } from 'lib/hooks/use-resetting-state.js'; -import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; +import type { + ReactionInfo, + ChatMessageInfoItem, +} from 'lib/selectors/chat-selectors.js'; import { useCanEditMessage } from 'lib/shared/edit-messages-utils.js'; import { createMessageReply } from 'lib/shared/message-utils.js'; import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js'; @@ -23,6 +26,7 @@ type MessageTooltipAction, getTooltipPositionStyle, calculateMessageTooltipSize, + calculateReactionTooltipSize, type TooltipPosition, type TooltipPositionStyle, type TooltipSize, @@ -30,6 +34,7 @@ import { getComposedMessageID } from '../chat/chat-constants.js'; import { useEditModalContext } from '../chat/edit-message-provider.js'; import MessageTooltip from '../chat/message-tooltip.react.js'; +import ReactionTooltip from '../chat/reaction-tooltip.react.js'; import { useTooltipContext } from '../chat/tooltip-provider.js'; import CommIcon from '../CommIcon.react.js'; import { InputStateContext } from '../input/input-state.js'; @@ -449,10 +454,58 @@ }; } +type UseReactionTooltipArgs = { + +reaction: string, + +reactions: ReactionInfo, + +availablePositions: $ReadOnlyArray, +}; + +function useReactionTooltip({ + reaction, + reactions, + availablePositions, +}: UseReactionTooltipArgs): UseTooltipResult { + const users = reactions[reaction].users; + + const tooltipSize = React.useMemo(() => { + if (typeof document === 'undefined') { + return { + width: 0, + height: 0, + }; + } + + const usernames = users.map(user => user.username).filter(Boolean); + const { width, height } = calculateReactionTooltipSize(usernames); + + return { + width, + height, + }; + }, [users]); + + const createReactionTooltip = React.useCallback( + () => , + [reaction, reactions], + ); + + const { onMouseEnter, onMouseLeave } = useTooltip({ + createTooltip: createReactionTooltip, + tooltipSize, + availablePositions, + }); + + return { + onMouseEnter, + onMouseLeave, + }; +} + export { useMessageTooltipSidebarAction, useMessageTooltipReplyAction, useMessageReactAction, useMessageTooltipActions, useMessageTooltip, + useReactionTooltip, };