Forum Panel: Optimize opening animation on Android (#2856)
This commit is contained in:
parent
fd7c7b5dc2
commit
1ad2e816a2
@ -64,7 +64,11 @@ const ArchivedChats: FC<OwnProps> = ({
|
|||||||
transitionClassNames: titleClassNames,
|
transitionClassNames: titleClassNames,
|
||||||
} = useShowTransition(!isForumPanelOpen);
|
} = useShowTransition(!isForumPanelOpen);
|
||||||
|
|
||||||
const { shouldRenderForumPanel, handleForumPanelAnimationEnd } = useForumPanelRender(isForumPanelOpen);
|
const {
|
||||||
|
shouldRenderForumPanel, handleForumPanelAnimationEnd,
|
||||||
|
handleForumPanelAnimationStart, isAnimationStarted,
|
||||||
|
} = useForumPanelRender(isForumPanelOpen);
|
||||||
|
const isForumPanelVisible = isForumPanelOpen && isAnimationStarted;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ArchivedChats">
|
<div className="ArchivedChats">
|
||||||
@ -78,7 +82,7 @@ const ArchivedChats: FC<OwnProps> = ({
|
|||||||
ariaLabel="Return to chat list"
|
ariaLabel="Return to chat list"
|
||||||
className={buildClassName(
|
className={buildClassName(
|
||||||
lang.isRtl && 'rtl',
|
lang.isRtl && 'rtl',
|
||||||
isForumPanelOpen && lang.isRtl && 'right-aligned',
|
isForumPanelVisible && lang.isRtl && 'right-aligned',
|
||||||
shouldDisableDropdownMenuTransitionRef.current && lang.isRtl && 'disable-transition',
|
shouldDisableDropdownMenuTransitionRef.current && lang.isRtl && 'disable-transition',
|
||||||
)}
|
)}
|
||||||
onTransitionEnd={handleDropdownMenuTransitionEnd}
|
onTransitionEnd={handleDropdownMenuTransitionEnd}
|
||||||
@ -101,7 +105,7 @@ const ArchivedChats: FC<OwnProps> = ({
|
|||||||
<ChatList
|
<ChatList
|
||||||
folderType="archived"
|
folderType="archived"
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
isForumPanelOpen={isForumPanelOpen}
|
isForumPanelOpen={isForumPanelVisible}
|
||||||
onSettingsScreenSelect={onSettingsScreenSelect}
|
onSettingsScreenSelect={onSettingsScreenSelect}
|
||||||
onLeftColumnContentChange={onLeftColumnContentChange}
|
onLeftColumnContentChange={onLeftColumnContentChange}
|
||||||
foldersDispatch={foldersDispatch}
|
foldersDispatch={foldersDispatch}
|
||||||
@ -111,6 +115,7 @@ const ArchivedChats: FC<OwnProps> = ({
|
|||||||
<ForumPanel
|
<ForumPanel
|
||||||
isOpen={isForumPanelOpen}
|
isOpen={isForumPanelOpen}
|
||||||
onTopicSearch={onTopicSearch}
|
onTopicSearch={onTopicSearch}
|
||||||
|
onOpenAnimationStart={handleForumPanelAnimationStart}
|
||||||
onCloseAnimationEnd={handleForumPanelAnimationEnd}
|
onCloseAnimationEnd={handleForumPanelAnimationEnd}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
|
|||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||||
import { selectCurrentLimit } from '../../../global/selectors/limits';
|
import { selectCurrentLimit } from '../../../global/selectors/limits';
|
||||||
import { selectTabState, selectIsForumPanelOpen } from '../../../global/selectors';
|
import { selectTabState } from '../../../global/selectors';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
@ -30,6 +30,7 @@ type OwnProps = {
|
|||||||
foldersDispatch: FolderEditDispatch;
|
foldersDispatch: FolderEditDispatch;
|
||||||
onLeftColumnContentChange: (content: LeftColumnContent) => void;
|
onLeftColumnContentChange: (content: LeftColumnContent) => void;
|
||||||
shouldHideFolderTabs?: boolean;
|
shouldHideFolderTabs?: boolean;
|
||||||
|
isForumPanelOpen?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
@ -37,7 +38,6 @@ type StateProps = {
|
|||||||
orderedFolderIds?: number[];
|
orderedFolderIds?: number[];
|
||||||
activeChatFolder: number;
|
activeChatFolder: number;
|
||||||
currentUserId?: string;
|
currentUserId?: string;
|
||||||
isForumPanelOpen?: boolean;
|
|
||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
shouldSkipHistoryAnimations?: boolean;
|
shouldSkipHistoryAnimations?: boolean;
|
||||||
maxFolders: number;
|
maxFolders: number;
|
||||||
@ -275,7 +275,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
orderedFolderIds,
|
orderedFolderIds,
|
||||||
activeChatFolder,
|
activeChatFolder,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
isForumPanelOpen: selectIsForumPanelOpen(global),
|
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
hasArchivedChats: Boolean(archived?.length),
|
hasArchivedChats: Boolean(archived?.length),
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import { getOrderedTopics } from '../../../global/helpers';
|
|||||||
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||||
import { waitForTransitionEnd } from '../../../util/cssAnimationEndListeners';
|
import { waitForTransitionEnd } from '../../../util/cssAnimationEndListeners';
|
||||||
import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
|
import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
|
||||||
|
import { fastRaf } from '../../../util/schedulers';
|
||||||
|
|
||||||
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
||||||
import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
||||||
@ -46,6 +47,7 @@ type OwnProps = {
|
|||||||
isHidden?: boolean;
|
isHidden?: boolean;
|
||||||
onTopicSearch?: NoneToVoidFunction;
|
onTopicSearch?: NoneToVoidFunction;
|
||||||
onCloseAnimationEnd?: VoidFunction;
|
onCloseAnimationEnd?: VoidFunction;
|
||||||
|
onOpenAnimationStart?: VoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
@ -65,6 +67,7 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
|
|||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
onTopicSearch,
|
onTopicSearch,
|
||||||
onCloseAnimationEnd,
|
onCloseAnimationEnd,
|
||||||
|
onOpenAnimationStart,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
@ -143,20 +146,27 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (prevIsVisible !== isVisible) {
|
if (prevIsVisible !== isVisible) {
|
||||||
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
// For performance reasons, we delay animation of the topic list panel to the next animation frame
|
||||||
waitForTransitionEnd(ref.current!, () => {
|
fastRaf(() => {
|
||||||
dispatchHeavyAnimationStop();
|
if (!ref.current) return;
|
||||||
});
|
|
||||||
|
|
||||||
if (isVisible) {
|
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||||
shouldRenderRef.current = true;
|
waitForTransitionEnd(ref.current, () => {
|
||||||
ref.current!.style.transform = 'none';
|
dispatchHeavyAnimationStop();
|
||||||
} else {
|
});
|
||||||
shouldRenderRef.current = false;
|
|
||||||
ref.current!.style.transform = '';
|
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(() => {
|
useEffect(() => {
|
||||||
if (!IS_TOUCH_ENV) {
|
if (!IS_TOUCH_ENV) {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import type { FC } from '../../../lib/teact/teact';
|
|||||||
import React, {
|
import React, {
|
||||||
memo, useCallback, useEffect, useRef, useState,
|
memo, useCallback, useEffect, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../../global';
|
||||||
|
|
||||||
import type { SettingsScreens } from '../../../types';
|
import type { SettingsScreens } from '../../../types';
|
||||||
import { LeftColumnContent } from '../../../types';
|
import { LeftColumnContent } from '../../../types';
|
||||||
@ -23,7 +24,6 @@ import Button from '../../ui/Button';
|
|||||||
import ForumPanel from './ForumPanel';
|
import ForumPanel from './ForumPanel';
|
||||||
|
|
||||||
import './LeftMain.scss';
|
import './LeftMain.scss';
|
||||||
import { getActions } from '../../../global';
|
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
content: LeftColumnContent;
|
content: LeftColumnContent;
|
||||||
@ -66,8 +66,12 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
const { closeForumPanel } = getActions();
|
const { closeForumPanel } = getActions();
|
||||||
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
|
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
|
||||||
|
|
||||||
const { shouldRenderForumPanel, handleForumPanelAnimationEnd } = useForumPanelRender(isForumPanelOpen);
|
const {
|
||||||
const isForumPanelVisible = isForumPanelOpen && content === LeftColumnContent.ChatList;
|
shouldRenderForumPanel, handleForumPanelAnimationEnd,
|
||||||
|
handleForumPanelAnimationStart, isAnimationStarted,
|
||||||
|
} = useForumPanelRender(isForumPanelOpen);
|
||||||
|
const isForumPanelRendered = isForumPanelOpen && content === LeftColumnContent.ChatList;
|
||||||
|
const isForumPanelVisible = isForumPanelRendered && isAnimationStarted;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shouldRender: shouldRenderUpdateButton,
|
shouldRender: shouldRenderUpdateButton,
|
||||||
@ -178,6 +182,7 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
onSettingsScreenSelect={onSettingsScreenSelect}
|
onSettingsScreenSelect={onSettingsScreenSelect}
|
||||||
onLeftColumnContentChange={onContentChange}
|
onLeftColumnContentChange={onContentChange}
|
||||||
foldersDispatch={foldersDispatch}
|
foldersDispatch={foldersDispatch}
|
||||||
|
isForumPanelOpen={isForumPanelVisible}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case LeftColumnContent.GlobalSearch:
|
case LeftColumnContent.GlobalSearch:
|
||||||
@ -209,8 +214,9 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
{shouldRenderForumPanel && (
|
{shouldRenderForumPanel && (
|
||||||
<ForumPanel
|
<ForumPanel
|
||||||
isOpen={isForumPanelOpen}
|
isOpen={isForumPanelOpen}
|
||||||
isHidden={!isForumPanelVisible}
|
isHidden={!isForumPanelRendered}
|
||||||
onTopicSearch={onTopicSearch}
|
onTopicSearch={onTopicSearch}
|
||||||
|
onOpenAnimationStart={handleForumPanelAnimationStart}
|
||||||
onCloseAnimationEnd={handleForumPanelAnimationEnd}
|
onCloseAnimationEnd={handleForumPanelAnimationEnd}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import useSyncEffect from './useSyncEffect';
|
|||||||
|
|
||||||
export default function useForumPanelRender(isForumPanelOpen = false) {
|
export default function useForumPanelRender(isForumPanelOpen = false) {
|
||||||
const shouldRenderForumPanelRef = useRef(isForumPanelOpen);
|
const shouldRenderForumPanelRef = useRef(isForumPanelOpen);
|
||||||
|
const isAnimationStartedRef = useRef(false);
|
||||||
const forceUpdate = useForceUpdate();
|
const forceUpdate = useForceUpdate();
|
||||||
|
|
||||||
useSyncEffect(() => {
|
useSyncEffect(() => {
|
||||||
@ -15,11 +16,19 @@ export default function useForumPanelRender(isForumPanelOpen = false) {
|
|||||||
|
|
||||||
const handleForumPanelAnimationEnd = useCallback(() => {
|
const handleForumPanelAnimationEnd = useCallback(() => {
|
||||||
shouldRenderForumPanelRef.current = false;
|
shouldRenderForumPanelRef.current = false;
|
||||||
|
isAnimationStartedRef.current = false;
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
}, [forceUpdate]);
|
}, [forceUpdate]);
|
||||||
|
|
||||||
|
const handleForumPanelAnimationStart = useCallback(() => {
|
||||||
|
isAnimationStartedRef.current = true;
|
||||||
|
forceUpdate();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
shouldRenderForumPanel: shouldRenderForumPanelRef.current,
|
shouldRenderForumPanel: shouldRenderForumPanelRef.current,
|
||||||
|
isAnimationStarted: isAnimationStartedRef.current,
|
||||||
handleForumPanelAnimationEnd,
|
handleForumPanelAnimationEnd,
|
||||||
|
handleForumPanelAnimationStart,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user