[Refactoring] Move beginHeavyAnimation and onFullyIdle to Teact
This commit is contained in:
parent
09203ae76e
commit
8b76de86ba
@ -1,6 +1,7 @@
|
||||
import type { RefObject } from 'react';
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
getIsHeavyAnimating,
|
||||
memo, useEffect, useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
|
||||
@ -17,7 +18,7 @@ import { IS_ELECTRON } from '../../util/windowEnvironment';
|
||||
import useColorFilter from '../../hooks/stickers/useColorFilter';
|
||||
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import useHeavyAnimationCheck, { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useHeavyAnimation from '../../hooks/useHeavyAnimation';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../hooks/usePriorityPlaybackCheck';
|
||||
import useSharedIntersectionObserver from '../../hooks/useSharedIntersectionObserver';
|
||||
@ -101,8 +102,8 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
// Delay initialization until heavy animation ends
|
||||
const [
|
||||
canInitialize, markCanInitialize, unmarkCanInitialize,
|
||||
] = useFlag(!isHeavyAnimating() || shouldForceOnHeavyAnimation);
|
||||
useHeavyAnimationCheck(unmarkCanInitialize, markCanInitialize, shouldForceOnHeavyAnimation);
|
||||
] = useFlag(!getIsHeavyAnimating() || shouldForceOnHeavyAnimation);
|
||||
useHeavyAnimation(unmarkCanInitialize, markCanInitialize, shouldForceOnHeavyAnimation);
|
||||
useEffect(() => {
|
||||
if (shouldForceOnHeavyAnimation) markCanInitialize();
|
||||
}, [shouldForceOnHeavyAnimation]);
|
||||
@ -129,7 +130,7 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
|| isUnmountedRef.current
|
||||
|| !tgsUrl
|
||||
|| (sharedCanvas && (!sharedCanvasCoords || !sharedCanvas.offsetWidth || !sharedCanvas.offsetHeight))
|
||||
|| (isHeavyAnimating() && !shouldForceOnHeavyAnimation)
|
||||
|| (getIsHeavyAnimating() && !shouldForceOnHeavyAnimation)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@ -252,7 +253,7 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
}
|
||||
}, [playAnimation, animation, tgsUrl]);
|
||||
|
||||
useHeavyAnimationCheck(pauseAnimation, playAnimation, !playKey || shouldForceOnHeavyAnimation);
|
||||
useHeavyAnimation(pauseAnimation, playAnimation, !playKey || shouldForceOnHeavyAnimation);
|
||||
usePriorityPlaybackCheck(pauseAnimation, playAnimation, !playKey || forceAlways);
|
||||
// Pausing frame may not happen in background,
|
||||
// so we need to make sure it happens right after focusing,
|
||||
@ -282,5 +283,5 @@ export default memo(AnimatedSticker);
|
||||
|
||||
function isFrozen(forceAlways = false, forceOnHeavyAnimation = false) {
|
||||
if (forceAlways) return false;
|
||||
return (!forceOnHeavyAnimation && isHeavyAnimating()) || isPriorityPlaybackActive() || isBackgroundModeActive();
|
||||
return (!forceOnHeavyAnimation && getIsHeavyAnimating()) || isPriorityPlaybackActive() || isBackgroundModeActive();
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import { preloadImage } from '../../../util/files';
|
||||
import { REM } from '../helpers/mediaDimensions';
|
||||
|
||||
import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener';
|
||||
import { useThrottleForHeavyAnimation } from '../../../hooks/useHeavyAnimationCheck';
|
||||
import { useThrottleForHeavyAnimation } from '../../../hooks/useHeavyAnimation';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useMedia from '../../../hooks/useMedia';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
memo, useEffect, useMemo, useRef, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
@ -22,7 +23,6 @@ import { waitForTransitionEnd } from '../../../util/cssAnimationEndListeners';
|
||||
import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
|
||||
|
||||
import useAppLayout from '../../../hooks/useAppLayout';
|
||||
import { dispatchHeavyAnimationEvent } from '../../../hooks/useHeavyAnimationCheck';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
||||
import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
||||
@ -148,8 +148,8 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
|
||||
requestNextMutation(() => {
|
||||
if (!ref.current) return;
|
||||
|
||||
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
waitForTransitionEnd(ref.current, dispatchHeavyAnimationStop);
|
||||
const endHeavyAnimation = beginHeavyAnimation();
|
||||
waitForTransitionEnd(ref.current, endHeavyAnimation);
|
||||
|
||||
onOpenAnimationStart?.();
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import '../../global/actions/all';
|
||||
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
memo, useEffect, useLayoutEffect,
|
||||
useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
@ -42,7 +43,6 @@ import useInterval from '../../hooks/schedulers/useInterval';
|
||||
import useTimeout from '../../hooks/schedulers/useTimeout';
|
||||
import useAppLayout from '../../hooks/useAppLayout';
|
||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import usePreventPinchZoomGesture from '../../hooks/usePreventPinchZoomGesture';
|
||||
import useShowTransition from '../../hooks/useShowTransition';
|
||||
@ -447,10 +447,10 @@ const Main = ({
|
||||
});
|
||||
}
|
||||
|
||||
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
|
||||
const endHeavyAnimation = beginHeavyAnimation();
|
||||
|
||||
waitForTransitionEnd(document.getElementById('MiddleColumn')!, () => {
|
||||
dispatchHeavyAnimationEnd();
|
||||
endHeavyAnimation();
|
||||
willAnimateLeftColumnRef.current = false;
|
||||
forceUpdate();
|
||||
});
|
||||
@ -480,10 +480,10 @@ const Main = ({
|
||||
|
||||
willAnimateRightColumnRef.current = true;
|
||||
|
||||
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
|
||||
const endHeavyAnimation = beginHeavyAnimation();
|
||||
|
||||
waitForTransitionEnd(document.getElementById('RightColumn')!, () => {
|
||||
dispatchHeavyAnimationEnd();
|
||||
endHeavyAnimation();
|
||||
willAnimateRightColumnRef.current = false;
|
||||
forceUpdate();
|
||||
setIsNarrowMessageList(isRightColumnOpen);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
memo, useEffect, useMemo, useRef,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
@ -40,7 +41,6 @@ import useAppLayout from '../../hooks/useAppLayout';
|
||||
import useElectronDrag from '../../hooks/useElectronDrag';
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
import { exitPictureInPictureIfNeeded, usePictureInPictureSignal } from '../../hooks/usePictureInPicture';
|
||||
@ -216,12 +216,12 @@ const MediaViewer = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (isGhostAnimation && isOpen && (shouldAnimateOpening || !prevItem)) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
animateOpening(hasFooter, origin!, bestImageData!, dimensions!, isVideo, message, mediaIndex);
|
||||
}
|
||||
|
||||
if (isGhostAnimation && !isOpen && prevItem) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
animateClosing(prevOrigin!, prevBestImageData!, prevMessage, prevItem?.mediaIndex);
|
||||
}
|
||||
}, [
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
memo, useEffect, useLayoutEffect, useRef,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
@ -13,7 +14,6 @@ import buildClassName from '../../util/buildClassName';
|
||||
import { IS_ANDROID } from '../../util/windowEnvironment';
|
||||
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import useMedia from '../../hooks/useMedia';
|
||||
|
||||
@ -74,11 +74,11 @@ const EmojiInteractionAnimation: FC<OwnProps & StateProps> = ({
|
||||
}, [handleCancelAnimation]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
const endHeavyAnimation = beginHeavyAnimation();
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
stop();
|
||||
dispatchHeavyAnimationStop();
|
||||
endHeavyAnimation();
|
||||
}, PLAYING_DURATION);
|
||||
}, [stop]);
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
memo,
|
||||
useEffect,
|
||||
useMemo,
|
||||
@ -66,7 +67,6 @@ import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
|
||||
|
||||
import useInterval from '../../hooks/schedulers/useInterval';
|
||||
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
||||
import useNativeCopySelectedMessages from '../../hooks/useNativeCopySelectedMessages';
|
||||
@ -629,7 +629,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
|
||||
useEffectWithPrevDeps(([prevIsSelectModeActive]) => {
|
||||
if (prevIsSelectModeActive !== undefined) {
|
||||
dispatchHeavyAnimationEvent(SELECT_MODE_ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(SELECT_MODE_ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
}
|
||||
}, [isSelectModeActive]);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { RefObject } from 'react';
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import React, { memo } from '../../lib/teact/teact';
|
||||
import React, { getIsHeavyAnimating, memo } from '../../lib/teact/teact';
|
||||
import { getActions } from '../../global';
|
||||
|
||||
import type { MessageListType } from '../../global/types';
|
||||
@ -25,7 +25,6 @@ import { isAlbum } from './helpers/groupMessages';
|
||||
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
|
||||
|
||||
import useDerivedSignal from '../../hooks/useDerivedSignal';
|
||||
import { getIsHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
|
||||
import useMessageObservers from './hooks/useMessageObservers';
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import type { ChangeEvent, RefObject } from 'react';
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
getIsHeavyAnimating,
|
||||
memo, useEffect, useLayoutEffect,
|
||||
useRef, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
@ -28,7 +29,6 @@ import { isSelectionInsideInput } from './helpers/selection';
|
||||
import useAppLayout from '../../../hooks/useAppLayout';
|
||||
import useDerivedState from '../../../hooks/useDerivedState';
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import { isHeavyAnimating } from '../../../hooks/useHeavyAnimationCheck';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
import useInputCustomEmojis from './hooks/useInputCustomEmojis';
|
||||
@ -265,7 +265,7 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (isHeavyAnimating()) {
|
||||
if (getIsHeavyAnimating()) {
|
||||
setTimeout(focusInput, FOCUS_DELAY_MS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
beginHeavyAnimation,
|
||||
memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
@ -126,7 +122,6 @@ import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
|
||||
import useEnsureMessage from '../../../hooks/useEnsureMessage';
|
||||
import useEnsureStory from '../../../hooks/useEnsureStory';
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import { dispatchHeavyAnimationEvent } from '../../../hooks/useHeavyAnimationCheck';
|
||||
import { useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
@ -832,7 +827,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
const container = entry.target.closest<HTMLDivElement>('.MessageList');
|
||||
if (!container) return;
|
||||
|
||||
dispatchHeavyAnimationEvent(RESIZE_ANIMATION_DURATION);
|
||||
beginHeavyAnimation(RESIZE_ANIMATION_DURATION);
|
||||
|
||||
const resizeDiff = newHeight - lastHeight;
|
||||
const { offsetHeight, scrollHeight, scrollTop } = container;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useEffect, useRef } from '../../../../lib/teact/teact';
|
||||
import { getIsHeavyAnimating, useEffect, useRef } from '../../../../lib/teact/teact';
|
||||
|
||||
import { requestMeasure } from '../../../../lib/fasterdom/fasterdom';
|
||||
|
||||
import useHeavyAnimationCheck, { isHeavyAnimating } from '../../../../hooks/useHeavyAnimationCheck';
|
||||
import useHeavyAnimation from '../../../../hooks/useHeavyAnimation';
|
||||
import useLastCallback from '../../../../hooks/useLastCallback';
|
||||
import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../../../hooks/usePriorityPlaybackCheck';
|
||||
import useBackgroundMode, { isBackgroundModeActive } from '../../../../hooks/window/useBackgroundMode';
|
||||
@ -26,7 +26,7 @@ export default function useVideoAutoPause(
|
||||
});
|
||||
|
||||
useBackgroundMode(pause, unfreezePlayingOnRaf, !canPlay || isPriority);
|
||||
useHeavyAnimationCheck(pause, unfreezePlaying, !canPlay || isPriority);
|
||||
useHeavyAnimation(pause, unfreezePlaying, !canPlay || isPriority);
|
||||
usePriorityPlaybackCheck(pause, unfreezePlaying, !canPlay || isPriority);
|
||||
|
||||
const handlePlaying = useLastCallback(() => {
|
||||
@ -81,5 +81,5 @@ function usePlayPause(mediaRef: React.RefObject<HTMLMediaElement>) {
|
||||
}
|
||||
|
||||
function isFrozen() {
|
||||
return isHeavyAnimating() || isPriorityPlaybackActive() || isBackgroundModeActive();
|
||||
return getIsHeavyAnimating() || isPriorityPlaybackActive() || isBackgroundModeActive();
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import React, { memo, useEffect, useMemo } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
beginHeavyAnimation, memo, useEffect, useMemo,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
|
||||
import type { ApiChat, ApiUser } from '../../api/types';
|
||||
@ -8,7 +10,6 @@ import { ANIMATION_END_DELAY, PREVIEW_AVATAR_COUNT } from '../../config';
|
||||
import { selectIsForumPanelOpen, selectPerformanceSettingsValue, selectTabState } from '../../global/selectors';
|
||||
import { animateClosing, animateOpening, ANIMATION_DURATION } from './helpers/ribbonAnimation';
|
||||
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
import useShowTransition from '../../hooks/useShowTransition';
|
||||
import useStoryPreloader from './hooks/useStoryPreloader';
|
||||
@ -98,10 +99,10 @@ function StoryToggler({
|
||||
useEffect(() => {
|
||||
if (!withAnimation || isForumPanelOpen) return;
|
||||
if (isVisible) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
animateClosing(isArchived);
|
||||
} else {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
animateOpening(isArchived);
|
||||
}
|
||||
}, [isArchived, isVisible, withAnimation, isForumPanelOpen]);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
memo, useCallback, useEffect, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
@ -19,7 +20,6 @@ import { disableDirectTextInput, enableDirectTextInput } from '../../util/direct
|
||||
import { animateClosing, animateOpening } from './helpers/ghostAnimation';
|
||||
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
|
||||
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
|
||||
@ -117,11 +117,11 @@ function StoryViewer({
|
||||
|
||||
useEffect(() => {
|
||||
if (isGhostAnimation && !isPrevOpen && isOpen && peerId && thumbnail && origin !== undefined) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
animateOpening(peerId, origin, thumbnail, bestImageData, slideSizes.activeSlide);
|
||||
}
|
||||
if (isGhostAnimation && isPrevOpen && !isOpen && prevPeerId && prevBestImageData && prevOrigin !== undefined) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
|
||||
animateClosing(prevPeerId, prevOrigin, prevBestImageData);
|
||||
}
|
||||
}, [
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React, {
|
||||
beginHeavyAnimation,
|
||||
type FC, memo, useEffect, useRef,
|
||||
} from '../../lib/teact/teact';
|
||||
|
||||
@ -11,7 +12,6 @@ import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMe
|
||||
|
||||
import useAppLayout from '../../hooks/useAppLayout';
|
||||
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
@ -100,7 +100,7 @@ const Menu: FC<OwnProps> = ({
|
||||
|
||||
useEffectWithPrevDeps(([prevIsOpen]) => {
|
||||
if (isOpen || (!isOpen && prevIsOpen === true)) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION);
|
||||
beginHeavyAnimation(ANIMATION_DURATION);
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { FC, TeactNode } from '../../lib/teact/teact';
|
||||
import React, { useEffect } from '../../lib/teact/teact';
|
||||
import React, { beginHeavyAnimation, useEffect } from '../../lib/teact/teact';
|
||||
|
||||
import type { TextPart } from '../../types';
|
||||
|
||||
@ -9,7 +9,6 @@ import { disableDirectTextInput, enableDirectTextInput } from '../../util/direct
|
||||
import freezeWhenClosed from '../../util/hoc/freezeWhenClosed';
|
||||
import trapFocus from '../../util/trapFocus';
|
||||
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
||||
@ -110,7 +109,7 @@ const Modal: FC<OwnProps> = ({
|
||||
document.body.classList.toggle('has-open-dialog', Boolean(isOpen));
|
||||
|
||||
if (isOpen || (!isOpen && prevIsOpen !== undefined)) {
|
||||
dispatchHeavyAnimationEvent(ANIMATION_DURATION);
|
||||
beginHeavyAnimation(ANIMATION_DURATION);
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { RefObject } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useRef } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
beginHeavyAnimation, useEffect, useLayoutEffect, useRef,
|
||||
} from '../../lib/teact/teact';
|
||||
import {
|
||||
addExtraClass, removeExtraClass, setExtraStyles, toggleExtraClass,
|
||||
} from '../../lib/teact/teact-dom';
|
||||
@ -14,7 +16,6 @@ import { omit } from '../../util/iteratees';
|
||||
import { allowSwipeControlForTransition } from '../../util/swipeController';
|
||||
|
||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
|
||||
|
||||
import './Transition.scss';
|
||||
@ -233,7 +234,7 @@ function Transition({
|
||||
});
|
||||
|
||||
isAnimatingRef.current = true;
|
||||
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
const endHeavyAnimation = beginHeavyAnimation();
|
||||
onStart?.();
|
||||
|
||||
toggleExtraClass(container, `Transition-${name}`, !isBackwards);
|
||||
@ -245,7 +246,7 @@ function Transition({
|
||||
|
||||
requestMutation(() => {
|
||||
if (activeKey !== currentKeyRef.current) {
|
||||
dispatchHeavyAnimationStop();
|
||||
endHeavyAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -269,7 +270,7 @@ function Transition({
|
||||
}
|
||||
|
||||
onStop?.();
|
||||
dispatchHeavyAnimationStop();
|
||||
endHeavyAnimation();
|
||||
isAnimatingRef.current = false;
|
||||
|
||||
cleanup();
|
||||
@ -291,7 +292,7 @@ function Transition({
|
||||
giveUpAnimationEnd();
|
||||
isSwipeJustCancelledRef.current = true;
|
||||
onStop?.();
|
||||
dispatchHeavyAnimationStop();
|
||||
endHeavyAnimation();
|
||||
isAnimatingRef.current = false;
|
||||
},
|
||||
);
|
||||
@ -424,7 +425,7 @@ function performSlideOptimized(
|
||||
}
|
||||
|
||||
isAnimatingRef.current = true;
|
||||
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
const endHeavyAnimation = beginHeavyAnimation();
|
||||
onStart?.();
|
||||
|
||||
toggleExtraClass(container, `Transition-${name}`, !isBackwards);
|
||||
@ -473,7 +474,7 @@ function performSlideOptimized(
|
||||
|
||||
requestMutation(() => {
|
||||
if (activeKey !== currentKeyRef.current) {
|
||||
dispatchHeavyAnimationStop();
|
||||
endHeavyAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -490,7 +491,7 @@ function performSlideOptimized(
|
||||
}
|
||||
|
||||
onStop?.();
|
||||
dispatchHeavyAnimationStop();
|
||||
endHeavyAnimation();
|
||||
isAnimatingRef.current = false;
|
||||
|
||||
cleanup();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/* eslint-disable eslint-multitab-tt/no-immediate-global */
|
||||
import { getIsHeavyAnimating, onFullyIdle } from '../lib/teact/teact';
|
||||
import { addCallback, removeCallback } from '../lib/teact/teactn';
|
||||
|
||||
import type { ApiAvailableReaction, ApiMessage } from '../api/types';
|
||||
@ -44,7 +45,6 @@ import {
|
||||
} from './selectors';
|
||||
|
||||
import { getIsMobile } from '../hooks/useAppLayout';
|
||||
import { isHeavyAnimating, onFullyIdle } from '../hooks/useHeavyAnimationCheck';
|
||||
|
||||
const UPDATE_THROTTLE = 5000;
|
||||
|
||||
@ -249,7 +249,7 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) {
|
||||
|
||||
function updateCache(force?: boolean) {
|
||||
const global = getGlobal();
|
||||
if (isRemovingCache || !isCaching || global.isLoggingOut || (!force && isHeavyAnimating())) {
|
||||
if (isRemovingCache || !isCaching || global.isLoggingOut || (!force && getIsHeavyAnimating())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { useCallback, useRef, useState } from '../lib/teact/teact';
|
||||
import {
|
||||
getIsHeavyAnimating, useCallback, useRef, useState,
|
||||
} from '../lib/teact/teact';
|
||||
|
||||
import useForceUpdate from './useForceUpdate';
|
||||
import useHeavyAnimationCheck, { isHeavyAnimating } from './useHeavyAnimationCheck';
|
||||
import useHeavyAnimation from './useHeavyAnimation';
|
||||
import useRunDebounced from './useRunDebounced';
|
||||
import useSyncEffect from './useSyncEffect';
|
||||
|
||||
@ -43,10 +45,10 @@ function useHeavyAnimationFreeze() {
|
||||
isPending.current = false;
|
||||
forceUpdate();
|
||||
}, [forceUpdate]);
|
||||
useHeavyAnimationCheck(noop, handleUnfreeze);
|
||||
useHeavyAnimation(noop, handleUnfreeze);
|
||||
|
||||
return {
|
||||
isFrozen: isHeavyAnimating(),
|
||||
isFrozen: getIsHeavyAnimating(),
|
||||
updateWhenUnfrozen,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,26 +1,23 @@
|
||||
import {
|
||||
getIsHeavyAnimating,
|
||||
useCallback, useEffect, useMemo, useRef,
|
||||
} from '../lib/teact/teact';
|
||||
|
||||
import { requestMeasure } from '../lib/fasterdom/fasterdom';
|
||||
import { createCallbackManager } from '../util/callbacks';
|
||||
import { onIdle } from '../util/schedulers';
|
||||
import { createSignal } from '../util/signals';
|
||||
import useLastCallback from './useLastCallback';
|
||||
|
||||
// Make sure to end even if end callback was not called (which was some hardly-reproducible bug)
|
||||
const AUTO_END_TIMEOUT = 1000;
|
||||
export const startCallbacks = createCallbackManager();
|
||||
export const endCallbacks = createCallbackManager();
|
||||
|
||||
const startCallbacks = createCallbackManager();
|
||||
const endCallbacks = createCallbackManager();
|
||||
getIsHeavyAnimating.subscribe(() => {
|
||||
if (getIsHeavyAnimating()) {
|
||||
startCallbacks.runCallbacks();
|
||||
} else {
|
||||
endCallbacks.runCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const [getIsAnimating, setIsAnimating] = createSignal(false);
|
||||
|
||||
export const getIsHeavyAnimating = getIsAnimating;
|
||||
|
||||
export default function useHeavyAnimationCheck(
|
||||
export default function useHeavyAnimation(
|
||||
onStart?: AnyToVoidFunction,
|
||||
onEnd?: AnyToVoidFunction,
|
||||
isDisabled = false,
|
||||
@ -33,7 +30,7 @@ export default function useHeavyAnimationCheck(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (getIsAnimating()) {
|
||||
if (getIsHeavyAnimating()) {
|
||||
lastOnStart();
|
||||
}
|
||||
|
||||
@ -57,7 +54,7 @@ export function useThrottleForHeavyAnimation<T extends AnyToVoidFunction>(afterH
|
||||
return useMemo(() => {
|
||||
return (...args: Parameters<T>) => {
|
||||
if (!isScheduledRef.current) {
|
||||
if (!getIsAnimating()) {
|
||||
if (!getIsHeavyAnimating()) {
|
||||
fnMemo(...args);
|
||||
return;
|
||||
}
|
||||
@ -73,48 +70,3 @@ export function useThrottleForHeavyAnimation<T extends AnyToVoidFunction>(afterH
|
||||
};
|
||||
}, [fnMemo]);
|
||||
}
|
||||
|
||||
export function isHeavyAnimating() {
|
||||
return getIsAnimating();
|
||||
}
|
||||
|
||||
export function dispatchHeavyAnimationEvent(duration = AUTO_END_TIMEOUT) {
|
||||
counter++;
|
||||
|
||||
if (counter === 1) {
|
||||
setIsAnimating(true);
|
||||
startCallbacks.runCallbacks();
|
||||
}
|
||||
|
||||
const timeout = window.setTimeout(onEnd, duration);
|
||||
|
||||
let hasEnded = false;
|
||||
|
||||
function onEnd() {
|
||||
if (hasEnded) return;
|
||||
hasEnded = true;
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
counter--;
|
||||
|
||||
if (counter === 0) {
|
||||
setIsAnimating(false);
|
||||
endCallbacks.runCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
return onEnd;
|
||||
}
|
||||
|
||||
export function onFullyIdle(cb: NoneToVoidFunction) {
|
||||
onIdle(() => {
|
||||
if (getIsAnimating()) {
|
||||
requestMeasure(() => {
|
||||
onFullyIdle(cb);
|
||||
});
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -7,7 +7,7 @@ import { type CallbackManager, createCallbackManager } from '../util/callbacks';
|
||||
import {
|
||||
debounce, throttle, throttleWith,
|
||||
} from '../util/schedulers';
|
||||
import useHeavyAnimationCheck from './useHeavyAnimationCheck';
|
||||
import useHeavyAnimation from './useHeavyAnimation';
|
||||
import useLastCallback from './useLastCallback';
|
||||
|
||||
type TargetCallback = (entry: IntersectionObserverEntry) => void;
|
||||
@ -71,7 +71,7 @@ export function useIntersectionObserver({
|
||||
}
|
||||
});
|
||||
|
||||
useHeavyAnimationCheck(freeze, unfreeze);
|
||||
useHeavyAnimation(freeze, unfreeze);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDisabled) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { useEffect, useSignal } from '../lib/teact/teact';
|
||||
import { getIsHeavyAnimating, useEffect, useSignal } from '../lib/teact/teact';
|
||||
|
||||
import useDerivedState from './useDerivedState';
|
||||
import { getIsHeavyAnimating } from './useHeavyAnimationCheck';
|
||||
|
||||
export default function useMountAfterHeavyAnimation(hasIntersected: boolean) {
|
||||
const [getNoHeavyAnimation, setNoHeavyAnimation] = useSignal(false);
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import type { RefObject } from 'react';
|
||||
import { useEffect } from '../lib/teact/teact';
|
||||
import { onFullyIdle, useEffect } from '../lib/teact/teact';
|
||||
|
||||
import unloadVideo from '../util/browser/unloadVideo';
|
||||
import { onFullyIdle } from './useHeavyAnimationCheck';
|
||||
|
||||
// Fix for memory leak when unmounting video element
|
||||
export default function useVideoCleanup(videoRef: RefObject<HTMLVideoElement>, dependencies: any[]) {
|
||||
|
||||
50
src/lib/teact/heavyAnimation.ts
Normal file
50
src/lib/teact/heavyAnimation.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { onIdle } from '../../util/schedulers';
|
||||
import { createSignal } from '../../util/signals';
|
||||
import { requestMeasure } from '../fasterdom/fasterdom';
|
||||
|
||||
const AUTO_END_TIMEOUT = 1000;
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const [getIsAnimating, setIsAnimating] = createSignal(false);
|
||||
|
||||
export const getIsHeavyAnimating = getIsAnimating;
|
||||
|
||||
export function beginHeavyAnimation(duration = AUTO_END_TIMEOUT) {
|
||||
counter++;
|
||||
|
||||
if (counter === 1) {
|
||||
setIsAnimating(true);
|
||||
}
|
||||
|
||||
const timeout = window.setTimeout(onEnd, duration);
|
||||
|
||||
let hasEnded = false;
|
||||
|
||||
function onEnd() {
|
||||
if (hasEnded) return;
|
||||
hasEnded = true;
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
counter--;
|
||||
|
||||
if (counter === 0) {
|
||||
setIsAnimating(false);
|
||||
}
|
||||
}
|
||||
|
||||
return onEnd;
|
||||
}
|
||||
|
||||
export function onFullyIdle(cb: NoneToVoidFunction) {
|
||||
onIdle(() => {
|
||||
if (getIsAnimating()) {
|
||||
requestMeasure(() => {
|
||||
onFullyIdle(cb);
|
||||
});
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -9,6 +9,8 @@ import { throttleWith } from '../../util/schedulers';
|
||||
import { createSignal, isSignal, type Signal } from '../../util/signals';
|
||||
import { requestMeasure, requestMutation } from '../fasterdom/fasterdom';
|
||||
|
||||
export { getIsHeavyAnimating, beginHeavyAnimation, onFullyIdle } from './heavyAnimation';
|
||||
|
||||
export type Props = AnyLiteral;
|
||||
export type FC<P extends Props = any> = (props: P) => any;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
|
||||
@ -6,10 +6,9 @@ import { handleError } from '../../util/handleError';
|
||||
import { orderBy } from '../../util/iteratees';
|
||||
import { throttleWithTickEnd } from '../../util/schedulers';
|
||||
import { requestMeasure } from '../fasterdom/fasterdom';
|
||||
import React, { DEBUG_resolveComponentName, useEffect } from './teact';
|
||||
import React, { DEBUG_resolveComponentName, getIsHeavyAnimating, useEffect } from './teact';
|
||||
|
||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||
import { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
|
||||
import useUniqueId from '../../hooks/useUniqueId';
|
||||
|
||||
export default React;
|
||||
@ -75,7 +74,7 @@ let forceOnHeavyAnimation = true;
|
||||
function runCallbacks() {
|
||||
if (forceOnHeavyAnimation) {
|
||||
forceOnHeavyAnimation = false;
|
||||
} else if (isHeavyAnimating()) {
|
||||
} else if (getIsHeavyAnimating()) {
|
||||
requestMeasure(runCallbacksThrottled);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { beginHeavyAnimation } from '../lib/teact/teact';
|
||||
import { getGlobal } from '../global';
|
||||
|
||||
import type { ScrollTargetPosition } from '../types';
|
||||
@ -14,13 +15,11 @@ import { selectCanAnimateInterface } from '../global/selectors';
|
||||
import { animateSingle, cancelSingleAnimation } from './animation';
|
||||
import { IS_ANDROID } from './windowEnvironment';
|
||||
|
||||
import { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';
|
||||
|
||||
type Params = Parameters<typeof createMutateFunction>;
|
||||
|
||||
let isAnimating = false;
|
||||
let currentArgs: Parameters<typeof createMutateFunction> | undefined;
|
||||
let onHeavyAnimationStop: NoneToVoidFunction | undefined;
|
||||
let onHeavyAnimationEnd: NoneToVoidFunction | undefined;
|
||||
|
||||
export default function animateScroll(...args: Params | [...Params, boolean]) {
|
||||
currentArgs = args.slice(0, 8) as Params;
|
||||
@ -127,9 +126,9 @@ function createMutateFunction(
|
||||
|
||||
isAnimating = true;
|
||||
|
||||
const prevOnHeavyAnimationStop = onHeavyAnimationStop;
|
||||
onHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
prevOnHeavyAnimationStop?.();
|
||||
const prevOnHeavyAnimationEnd = onHeavyAnimationEnd;
|
||||
onHeavyAnimationEnd = beginHeavyAnimation();
|
||||
prevOnHeavyAnimationEnd?.();
|
||||
|
||||
animateSingle(() => {
|
||||
const t = Math.min((Date.now() - startAt) / duration, 1);
|
||||
@ -143,8 +142,8 @@ function createMutateFunction(
|
||||
if (!isAnimating) {
|
||||
currentArgs = undefined;
|
||||
|
||||
onHeavyAnimationStop!();
|
||||
onHeavyAnimationStop = undefined;
|
||||
onHeavyAnimationEnd!();
|
||||
onHeavyAnimationEnd = undefined;
|
||||
}
|
||||
|
||||
return isAnimating;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { onFullyIdle } from '../lib/teact/teact';
|
||||
import { addCallback } from '../lib/teact/teactn';
|
||||
import { addActionHandler, getGlobal } from '../global';
|
||||
|
||||
@ -23,8 +24,6 @@ import { createCallbackManager } from './callbacks';
|
||||
import { areSortedArraysEqual, unique } from './iteratees';
|
||||
import { throttle } from './schedulers';
|
||||
|
||||
import { onFullyIdle } from '../hooks/useHeavyAnimationCheck';
|
||||
|
||||
interface FolderSummary {
|
||||
id: number;
|
||||
listIds?: Set<string>;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/* eslint-disable eslint-multitab-tt/set-global-only-variable */
|
||||
import { onFullyIdle } from '../lib/teact/teact';
|
||||
import { addCallback } from '../lib/teact/teactn';
|
||||
import { getActions, getGlobal, setGlobal } from '../global';
|
||||
|
||||
@ -24,8 +25,6 @@ import { getCurrentTabId, signalPasscodeHash, subscribeToTokenDied } from './est
|
||||
import { omit } from './iteratees';
|
||||
import { IS_MULTITAB_SUPPORTED } from './windowEnvironment';
|
||||
|
||||
import { onFullyIdle } from '../hooks/useHeavyAnimationCheck';
|
||||
|
||||
type BroadcastChannelRefreshLangpack = {
|
||||
type: 'langpackRefresh';
|
||||
langCode: string;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user