From 8f1b32cdb43485c8174237528067b8fa93265651 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 21 Jan 2022 17:29:32 +0100 Subject: [PATCH] Message Context Menu: Fix flickering (#1646) --- src/components/middle/message/MessageContextMenu.tsx | 11 ++++++++++- src/hooks/useContextMenuPosition.ts | 9 +++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/middle/message/MessageContextMenu.tsx b/src/components/middle/message/MessageContextMenu.tsx index c77e69222..a2f4c3f57 100644 --- a/src/components/middle/message/MessageContextMenu.tsx +++ b/src/components/middle/message/MessageContextMenu.tsx @@ -11,6 +11,7 @@ import useContextMenuPosition from '../../../hooks/useContextMenuPosition'; import useLang from '../../../hooks/useLang'; import buildClassName from '../../../util/buildClassName'; import useFlag from '../../../hooks/useFlag'; +import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment'; import Menu from '../../ui/Menu'; import MenuItem from '../../ui/MenuItem'; @@ -159,6 +160,13 @@ const MessageContextMenu: FC = ({ }, ANIMATION_DURATION); }, [isOpen, markIsReady, unmarkIsReady]); + const extraHeightAudioPlayer = (IS_SINGLE_COLUMN_LAYOUT + && (document.querySelector('.AudioPlayer-content'))?.offsetHeight) || 0; + const pinnedElement = document.querySelector('.HeaderPinnedMessage-wrapper'); + const extraHeightPinned = (((IS_SINGLE_COLUMN_LAYOUT && !extraHeightAudioPlayer) + || (!IS_SINGLE_COLUMN_LAYOUT && pinnedElement?.classList.contains('full-width'))) + && pinnedElement?.offsetHeight) || 0; + const { positionX, positionY, style, menuStyle, withScroll, } = useContextMenuPosition( @@ -167,8 +175,9 @@ const MessageContextMenu: FC = ({ getRootElement, getMenuElement, SCROLLBAR_WIDTH, - (document.querySelector('.MiddleHeader') as HTMLElement).offsetHeight, + (document.querySelector('.MiddleHeader')!).offsetHeight, withReactions ? REACTION_BUBBLE_EXTRA_WIDTH : undefined, + extraHeightPinned + extraHeightAudioPlayer, ); useEffect(() => { diff --git a/src/hooks/useContextMenuPosition.ts b/src/hooks/useContextMenuPosition.ts index f0ec1976a..92ce89ecf 100644 --- a/src/hooks/useContextMenuPosition.ts +++ b/src/hooks/useContextMenuPosition.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from '../lib/teact/teact'; +import { useState, useLayoutEffect } from '../lib/teact/teact'; import { IAnchorPosition } from '../types'; const MENU_POSITION_VISUAL_COMFORT_SPACE_PX = 16; @@ -12,6 +12,7 @@ export default ( extraPaddingX = 0, extraTopPadding = 0, marginSides = 0, + extraMarginTop = 0, ) => { const [positionX, setPositionX] = useState<'right' | 'left'>('right'); const [positionY, setPositionY] = useState<'top' | 'bottom'>('bottom'); @@ -19,7 +20,7 @@ export default ( const [style, setStyle] = useState(''); const [menuStyle, setMenuStyle] = useState(''); - useEffect(() => { + useLayoutEffect(() => { const triggerEl = getTriggerElement(); if (!anchor || !triggerEl) { return; @@ -35,7 +36,7 @@ export default ( const triggerRect = triggerEl.getBoundingClientRect(); - const marginTop = menuEl ? parseInt(getComputedStyle(menuEl).marginTop, 10) : undefined; + const marginTop = menuEl ? parseInt(getComputedStyle(menuEl).marginTop, 10) + extraMarginTop : undefined; const menuRect = menuEl ? { width: menuEl.offsetWidth, @@ -93,7 +94,7 @@ export default ( setMenuStyle(`max-height: ${menuMaxHeight}px;`); setStyle(`left: ${left}px; top: ${top}px`); }, [ - anchor, extraPaddingX, extraTopPadding, + anchor, extraPaddingX, extraTopPadding, extraMarginTop, getMenuElement, getRootElement, getTriggerElement, marginSides, ]);