diff --git a/src/components/middle/MiddleColumn.tsx b/src/components/middle/MiddleColumn.tsx index 37956c2c1..479d790ff 100644 --- a/src/components/middle/MiddleColumn.tsx +++ b/src/components/middle/MiddleColumn.tsx @@ -1,6 +1,6 @@ import type React from '@teact'; import type { ElementRef } from '@teact'; -import { memo, useEffect, useMemo, useState } from '@teact'; +import { memo, useEffect, useMemo, useRef, useState } from '@teact'; import { getActions, withGlobal } from '../../global'; import type { ApiChat, ApiChatBannedRights, ApiInputMessageReplyInfo, ApiTopic } from '../../api/types'; @@ -61,6 +61,7 @@ import { import buildClassName from '../../util/buildClassName'; import buildStyle from '../../util/buildStyle'; import captureEscKeyListener from '../../util/captureEscKeyListener'; +import { waitForTransitionEnd } from '../../util/cssAnimationEndListeners'; import { isUserId } from '../../util/entities/ids'; import { resolveTransitionName } from '../../util/resolveTransitionName'; import calculateMiddleFooterTransforms from './helpers/calculateMiddleFooterTransforms'; @@ -292,12 +293,16 @@ function MiddleColumn({ prevTransitionKey !== undefined && prevTransitionKey < currentTransitionKey ? prevTransitionKey : undefined ); - const { isReady, handleCssTransitionEnd, handleSlideTransitionStop } = useIsReady( + const middleColumnRef = useRef(); + + const { isReady, handleSlideTransitionStop } = useIsReady( !shouldSkipHistoryAnimations && withInterfaceAnimations, currentTransitionKey, prevTransitionKey, chatId, isMobile, + isLeftColumnShown, + middleColumnRef, ); useEffect(() => { @@ -501,9 +506,9 @@ function MiddleColumn({ return (
, ) { const [isReady, setIsReady] = useState(!isMobile); const forceUpdate = useForceUpdate(); @@ -910,13 +917,9 @@ function useIsReady( setIsReady(false); // Make sure to end even if end callback was not called (which was some hardly-reproducible bug) - const timeout = setTimeout(() => { + window.setTimeout(() => { setIsReady(true); }, LAYER_ANIMATION_DURATION_MS); - - return () => { - clearTimeout(timeout); - }; }, [willSwitchMessageList, withAnimations]); useSyncEffect(() => { @@ -925,11 +928,40 @@ function useIsReady( } }, [withAnimations]); - function handleCssTransitionEnd(e: React.TransitionEvent) { - if (e.propertyName === 'transform' && e.target === e.currentTarget) { - setIsReady(Boolean(chatId)); + // Mobile only: wait until `MiddleColumn` slides in after the left column closes + useSyncEffect(([prevIsLeftColumnShown, prevWillSwitchMessageList]) => { + if (!isMobile) { + return; } - } + + if (!chatId) { + setIsReady(false); + return; + } + + if (!withAnimations) { + setIsReady(true); + return; + } + + if (willSwitchMessageList || prevWillSwitchMessageList) { + return; + } + + if (isLeftColumnShown) { + setIsReady(false); + return; + } + + if (prevIsLeftColumnShown !== true) { + setIsReady(true); + return; + } + + waitForTransitionEnd(middleColumnRef!.current!, () => { + setIsReady(true); + }, 'transform', LAYER_ANIMATION_DURATION_MS); + }, [isLeftColumnShown, willSwitchMessageList, chatId, isMobile, withAnimations, middleColumnRef]); function handleSlideTransitionStop() { setIsReady(true); @@ -937,7 +969,6 @@ function useIsReady( return { isReady: isReady && !willSwitchMessageList, - handleCssTransitionEnd: withAnimations ? handleCssTransitionEnd : undefined, handleSlideTransitionStop: withAnimations ? handleSlideTransitionStop : undefined, }; } diff --git a/src/util/cssAnimationEndListeners.ts b/src/util/cssAnimationEndListeners.ts index 2731339dc..0490b7964 100644 --- a/src/util/cssAnimationEndListeners.ts +++ b/src/util/cssAnimationEndListeners.ts @@ -32,8 +32,8 @@ function waitForEndEvent( } if (detailedName && ( - (e instanceof TransitionEvent && e.propertyName === detailedName) - || (e instanceof AnimationEvent && e.animationName === detailedName) + (e instanceof TransitionEvent && e.propertyName !== detailedName) + || (e instanceof AnimationEvent && e.animationName !== detailedName) )) { return; }