diff --git a/web/chat/reaction-message-utils.js b/web/chat/reaction-message-utils.js --- a/web/chat/reaction-message-utils.js +++ b/web/chat/reaction-message-utils.js @@ -18,6 +18,11 @@ import Alert from '../modals/alert.react.js'; import { useSelector } from '../redux/redux-utils.js'; +import { + type TooltipSize, + type TooltipPositionStyle, +} from '../utils/tooltip-utils.js'; +import { getAppContainerPositionInfo } from '../utils/window-utils.js'; function useSendReaction( messageID: ?string, @@ -101,4 +106,101 @@ ); } -export { useSendReaction }; +type EmojiKeyboardPosition = { + +bottom: number, + +left: number, +}; + +function getEmojiKeyboardPosition( + emojiKeyboard: ?HTMLDivElement, + tooltipPositionStyle: TooltipPositionStyle, + tooltipSize: TooltipSize, +): EmojiKeyboardPosition { + const { alignment, anchorPoint } = tooltipPositionStyle; + const tooltipAnchorX = anchorPoint.x; + const tooltipAnchorY = anchorPoint.y; + + const tooltipWidth = tooltipSize.width; + const tooltipHeight = tooltipSize.height; + + const appContainerPositionInfo = getAppContainerPositionInfo(); + invariant(appContainerPositionInfo, 'appContainerPositionInfo must be set'); + + let emojiKeyboardWidth = 352; + let emojiKeyboardHeight = 435; + + if (emojiKeyboard) { + const { width, height } = emojiKeyboard.getBoundingClientRect(); + emojiKeyboardWidth = width; + emojiKeyboardHeight = height; + } + + const { + top: containerTop, + left: containerLeft, + right: containerRight, + bottom: containerBottom, + } = appContainerPositionInfo; + + const padding = 16; + + const canBeDisplayedOnRight = + tooltipAnchorX + tooltipWidth + emojiKeyboardWidth <= containerRight; + + const canBeDisplayedOnLeft = + tooltipAnchorX - emojiKeyboardWidth >= containerLeft; + + const canBeDisplayedOnTop = + tooltipAnchorY - emojiKeyboardHeight - padding >= containerTop; + + const canBeDisplayedOnBottom = + tooltipAnchorY + tooltipHeight + emojiKeyboardHeight + padding <= + containerBottom; + + const emojiKeyboardOverflowTop = + containerTop - (tooltipAnchorY + tooltipHeight - emojiKeyboardHeight); + + const emojiKeyboardOverflowTopCorrection = + emojiKeyboardOverflowTop > 0 ? -emojiKeyboardOverflowTop - padding : 0; + + const emojiKeyboardOverflowRight = + tooltipAnchorX + emojiKeyboardWidth - containerRight; + + const emojiKeyboardOverflowRightCorrection = + emojiKeyboardOverflowRight > 0 ? -emojiKeyboardOverflowRight - padding : 0; + + if (alignment === 'left' && canBeDisplayedOnRight) { + return { + left: tooltipWidth, + bottom: emojiKeyboardOverflowTopCorrection, + }; + } + + if (alignment === 'right' && canBeDisplayedOnLeft) { + return { + left: -emojiKeyboardWidth, + bottom: emojiKeyboardOverflowTopCorrection, + }; + } + + if (canBeDisplayedOnTop) { + return { + bottom: tooltipHeight + padding, + left: emojiKeyboardOverflowRightCorrection, + }; + } + + if (canBeDisplayedOnBottom) { + return { + bottom: -emojiKeyboardHeight - padding, + left: emojiKeyboardOverflowRightCorrection, + }; + } + + return { + left: alignment === 'left' ? -emojiKeyboardWidth : tooltipWidth, + bottom: emojiKeyboardOverflowTopCorrection, + }; +} + +export { useSendReaction, getEmojiKeyboardPosition }; 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 @@ -47,7 +47,7 @@ BOTTOM: 'bottom', }); -type TooltipSize = { +export type TooltipSize = { +height: number, +width: number, };