diff --git a/packages/react/src/views/EmojiReaction/EmojiReaction.js b/packages/react/src/views/EmojiReaction/EmojiReaction.js index a85dfc92fc..80ba34d76e 100644 --- a/packages/react/src/views/EmojiReaction/EmojiReaction.js +++ b/packages/react/src/views/EmojiReaction/EmojiReaction.js @@ -7,7 +7,7 @@ import DOMPurify from 'dompurify'; const EmojiReaction = ({ body }) => { const emojiHtml = emojione.toImage(body); - + emojione.imageTitleTag = false; return ( { reactionMine: css` background: ${theme.colors.secondary}; `, + emojiTooltip: css` + position: absolute; + bottom: 120%; + left: 50%; + transform: translateX(-40%); + background-color: ${theme.invertedColors.secondary}; + color: ${theme.invertedColors.secondaryForeground}; + z-index: ${theme.zIndex?.tooltip || 1400}; + border-radius: ${theme.radius}; + padding: 8px 10px; + width: 200px; + white-space: normal; + overflow-wrap: break-word; + word-break: break-word; + font-size: 0.85rem; + `, }; return styles; diff --git a/packages/react/src/views/Message/MessageReactions.js b/packages/react/src/views/Message/MessageReactions.js index 5f05a684d0..39a0cc6f96 100644 --- a/packages/react/src/views/Message/MessageReactions.js +++ b/packages/react/src/views/Message/MessageReactions.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useMemo } from 'react'; import { Box, useComponentOverrides, @@ -24,6 +24,44 @@ export const MessageReactions = ({ ); const { theme } = useTheme(); const styles = getMessageReactionsStyles(theme); + const [hoveredReaction, setHoveredReaction] = useState(null); + + const tooltipMap = useMemo(() => { + const map = {}; + if (message.reactions) { + serializeReactions(message.reactions).forEach((reaction) => { + const usernames = reaction.usernames || []; + const updatedUsernames = []; + let isUserIncluded = false; + + usernames.forEach((username) => { + if (username === authenticatedUserUsername) { + isUserIncluded = true; + } else { + updatedUsernames.push(username); + } + }); + + if (isUserIncluded) { + updatedUsernames.unshift('You'); + } + + const visibleNames = updatedUsernames.slice(0, 9); + const remainingCount = updatedUsernames.length - visibleNames.length; + + let tooltipContent = visibleNames.join(', '); + if (remainingCount > 0) { + tooltipContent += `, and ${remainingCount} ${ + remainingCount === 1 ? 'other' : 'others' + }`; + } + + map[reaction.name] = `${tooltipContent} reacted with ${reaction.name}`; + }); + } + return map; + }, [message.reactions, authenticatedUserUsername]); + return ( {message.reactions && - serializeReactions(message.reactions).map((reaction) => ( - - handleEmojiClick( - reaction, - message, - !isSameUser(reaction, authenticatedUserUsername) - ) - } - > - -

{reaction.count}

-
- ))} + serializeReactions(message.reactions).map((reaction) => { + const isUserReaction = isSameUser( + reaction, + authenticatedUserUsername + ); + return ( + + handleEmojiClick(reaction, message, !isUserReaction) + } + onMouseEnter={() => setHoveredReaction(reaction.name)} + onMouseLeave={() => setHoveredReaction(null)} + style={{ position: 'relative' }} + > + +

{reaction.count}

+ {hoveredReaction === reaction.name && ( + {tooltipMap[reaction.name]} + )} +
+ ); + })}
); };