Forum Panel: Optimize opening animation on Android (#2856)

This commit is contained in:
Alexander Zinchuk 2023-03-30 18:25:14 -05:00
parent fd7c7b5dc2
commit 1ad2e816a2
5 changed files with 51 additions and 22 deletions

View File

@ -64,7 +64,11 @@ const ArchivedChats: FC<OwnProps> = ({
transitionClassNames: titleClassNames,
} = useShowTransition(!isForumPanelOpen);
const { shouldRenderForumPanel, handleForumPanelAnimationEnd } = useForumPanelRender(isForumPanelOpen);
const {
shouldRenderForumPanel, handleForumPanelAnimationEnd,
handleForumPanelAnimationStart, isAnimationStarted,
} = useForumPanelRender(isForumPanelOpen);
const isForumPanelVisible = isForumPanelOpen && isAnimationStarted;
return (
<div className="ArchivedChats">
@ -78,7 +82,7 @@ const ArchivedChats: FC<OwnProps> = ({
ariaLabel="Return to chat list"
className={buildClassName(
lang.isRtl && 'rtl',
isForumPanelOpen && lang.isRtl && 'right-aligned',
isForumPanelVisible && lang.isRtl && 'right-aligned',
shouldDisableDropdownMenuTransitionRef.current && lang.isRtl && 'disable-transition',
)}
onTransitionEnd={handleDropdownMenuTransitionEnd}
@ -101,7 +105,7 @@ const ArchivedChats: FC<OwnProps> = ({
<ChatList
folderType="archived"
isActive={isActive}
isForumPanelOpen={isForumPanelOpen}
isForumPanelOpen={isForumPanelVisible}
onSettingsScreenSelect={onSettingsScreenSelect}
onLeftColumnContentChange={onLeftColumnContentChange}
foldersDispatch={foldersDispatch}
@ -111,6 +115,7 @@ const ArchivedChats: FC<OwnProps> = ({
<ForumPanel
isOpen={isForumPanelOpen}
onTopicSearch={onTopicSearch}
onOpenAnimationStart={handleForumPanelAnimationStart}
onCloseAnimationEnd={handleForumPanelAnimationEnd}
/>
)}

View File

@ -15,7 +15,7 @@ import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
import buildClassName from '../../../util/buildClassName';
import captureEscKeyListener from '../../../util/captureEscKeyListener';
import { selectCurrentLimit } from '../../../global/selectors/limits';
import { selectTabState, selectIsForumPanelOpen } from '../../../global/selectors';
import { selectTabState } from '../../../global/selectors';
import useShowTransition from '../../../hooks/useShowTransition';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -30,6 +30,7 @@ type OwnProps = {
foldersDispatch: FolderEditDispatch;
onLeftColumnContentChange: (content: LeftColumnContent) => void;
shouldHideFolderTabs?: boolean;
isForumPanelOpen?: boolean;
};
type StateProps = {
@ -37,7 +38,6 @@ type StateProps = {
orderedFolderIds?: number[];
activeChatFolder: number;
currentUserId?: string;
isForumPanelOpen?: boolean;
lastSyncTime?: number;
shouldSkipHistoryAnimations?: boolean;
maxFolders: number;
@ -275,7 +275,6 @@ export default memo(withGlobal<OwnProps>(
orderedFolderIds,
activeChatFolder,
currentUserId,
isForumPanelOpen: selectIsForumPanelOpen(global),
lastSyncTime,
shouldSkipHistoryAnimations,
hasArchivedChats: Boolean(archived?.length),

View File

@ -20,6 +20,7 @@ import { getOrderedTopics } from '../../../global/helpers';
import captureEscKeyListener from '../../../util/captureEscKeyListener';
import { waitForTransitionEnd } from '../../../util/cssAnimationEndListeners';
import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
import { fastRaf } from '../../../util/schedulers';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver';
@ -46,6 +47,7 @@ type OwnProps = {
isHidden?: boolean;
onTopicSearch?: NoneToVoidFunction;
onCloseAnimationEnd?: VoidFunction;
onOpenAnimationStart?: VoidFunction;
};
type StateProps = {
@ -65,6 +67,7 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
lastSyncTime,
onTopicSearch,
onCloseAnimationEnd,
onOpenAnimationStart,
animationLevel,
}) => {
const {
@ -143,20 +146,27 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
useEffect(() => {
if (prevIsVisible !== isVisible) {
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
waitForTransitionEnd(ref.current!, () => {
dispatchHeavyAnimationStop();
});
// For performance reasons, we delay animation of the topic list panel to the next animation frame
fastRaf(() => {
if (!ref.current) return;
if (isVisible) {
shouldRenderRef.current = true;
ref.current!.style.transform = 'none';
} else {
shouldRenderRef.current = false;
ref.current!.style.transform = '';
}
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
waitForTransitionEnd(ref.current, () => {
dispatchHeavyAnimationStop();
});
onOpenAnimationStart?.();
if (isVisible) {
shouldRenderRef.current = true;
ref.current!.style.transform = 'none';
} else {
shouldRenderRef.current = false;
ref.current!.style.transform = '';
}
});
}
}, [isVisible, prevIsVisible]);
}, [isVisible, onOpenAnimationStart, prevIsVisible]);
useEffect(() => {
if (!IS_TOUCH_ENV) {

View File

@ -2,6 +2,7 @@ import type { FC } from '../../../lib/teact/teact';
import React, {
memo, useCallback, useEffect, useRef, useState,
} from '../../../lib/teact/teact';
import { getActions } from '../../../global';
import type { SettingsScreens } from '../../../types';
import { LeftColumnContent } from '../../../types';
@ -23,7 +24,6 @@ import Button from '../../ui/Button';
import ForumPanel from './ForumPanel';
import './LeftMain.scss';
import { getActions } from '../../../global';
type OwnProps = {
content: LeftColumnContent;
@ -66,8 +66,12 @@ const LeftMain: FC<OwnProps> = ({
const { closeForumPanel } = getActions();
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
const { shouldRenderForumPanel, handleForumPanelAnimationEnd } = useForumPanelRender(isForumPanelOpen);
const isForumPanelVisible = isForumPanelOpen && content === LeftColumnContent.ChatList;
const {
shouldRenderForumPanel, handleForumPanelAnimationEnd,
handleForumPanelAnimationStart, isAnimationStarted,
} = useForumPanelRender(isForumPanelOpen);
const isForumPanelRendered = isForumPanelOpen && content === LeftColumnContent.ChatList;
const isForumPanelVisible = isForumPanelRendered && isAnimationStarted;
const {
shouldRender: shouldRenderUpdateButton,
@ -178,6 +182,7 @@ const LeftMain: FC<OwnProps> = ({
onSettingsScreenSelect={onSettingsScreenSelect}
onLeftColumnContentChange={onContentChange}
foldersDispatch={foldersDispatch}
isForumPanelOpen={isForumPanelVisible}
/>
);
case LeftColumnContent.GlobalSearch:
@ -209,8 +214,9 @@ const LeftMain: FC<OwnProps> = ({
{shouldRenderForumPanel && (
<ForumPanel
isOpen={isForumPanelOpen}
isHidden={!isForumPanelVisible}
isHidden={!isForumPanelRendered}
onTopicSearch={onTopicSearch}
onOpenAnimationStart={handleForumPanelAnimationStart}
onCloseAnimationEnd={handleForumPanelAnimationEnd}
/>
)}

View File

@ -5,6 +5,7 @@ import useSyncEffect from './useSyncEffect';
export default function useForumPanelRender(isForumPanelOpen = false) {
const shouldRenderForumPanelRef = useRef(isForumPanelOpen);
const isAnimationStartedRef = useRef(false);
const forceUpdate = useForceUpdate();
useSyncEffect(() => {
@ -15,11 +16,19 @@ export default function useForumPanelRender(isForumPanelOpen = false) {
const handleForumPanelAnimationEnd = useCallback(() => {
shouldRenderForumPanelRef.current = false;
isAnimationStartedRef.current = false;
forceUpdate();
}, [forceUpdate]);
const handleForumPanelAnimationStart = useCallback(() => {
isAnimationStartedRef.current = true;
forceUpdate();
}, []);
return {
shouldRenderForumPanel: shouldRenderForumPanelRef.current,
isAnimationStarted: isAnimationStartedRef.current,
handleForumPanelAnimationEnd,
handleForumPanelAnimationStart,
};
}