[Refactoring] Move beginHeavyAnimation and onFullyIdle to Teact

This commit is contained in:
Alexander Zinchuk 2024-09-19 20:43:18 +02:00
parent 09203ae76e
commit 8b76de86ba
29 changed files with 144 additions and 148 deletions

View File

@ -1,6 +1,7 @@
import type { RefObject } from 'react'; import type { RefObject } from 'react';
import type { FC } from '../../lib/teact/teact'; import type { FC } from '../../lib/teact/teact';
import React, { import React, {
getIsHeavyAnimating,
memo, useEffect, useRef, useState, memo, useEffect, useRef, useState,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
@ -17,7 +18,7 @@ import { IS_ELECTRON } from '../../util/windowEnvironment';
import useColorFilter from '../../hooks/stickers/useColorFilter'; import useColorFilter from '../../hooks/stickers/useColorFilter';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import useHeavyAnimationCheck, { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck'; import useHeavyAnimation from '../../hooks/useHeavyAnimation';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../hooks/usePriorityPlaybackCheck'; import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../hooks/usePriorityPlaybackCheck';
import useSharedIntersectionObserver from '../../hooks/useSharedIntersectionObserver'; import useSharedIntersectionObserver from '../../hooks/useSharedIntersectionObserver';
@ -101,8 +102,8 @@ const AnimatedSticker: FC<OwnProps> = ({
// Delay initialization until heavy animation ends // Delay initialization until heavy animation ends
const [ const [
canInitialize, markCanInitialize, unmarkCanInitialize, canInitialize, markCanInitialize, unmarkCanInitialize,
] = useFlag(!isHeavyAnimating() || shouldForceOnHeavyAnimation); ] = useFlag(!getIsHeavyAnimating() || shouldForceOnHeavyAnimation);
useHeavyAnimationCheck(unmarkCanInitialize, markCanInitialize, shouldForceOnHeavyAnimation); useHeavyAnimation(unmarkCanInitialize, markCanInitialize, shouldForceOnHeavyAnimation);
useEffect(() => { useEffect(() => {
if (shouldForceOnHeavyAnimation) markCanInitialize(); if (shouldForceOnHeavyAnimation) markCanInitialize();
}, [shouldForceOnHeavyAnimation]); }, [shouldForceOnHeavyAnimation]);
@ -129,7 +130,7 @@ const AnimatedSticker: FC<OwnProps> = ({
|| isUnmountedRef.current || isUnmountedRef.current
|| !tgsUrl || !tgsUrl
|| (sharedCanvas && (!sharedCanvasCoords || !sharedCanvas.offsetWidth || !sharedCanvas.offsetHeight)) || (sharedCanvas && (!sharedCanvasCoords || !sharedCanvas.offsetWidth || !sharedCanvas.offsetHeight))
|| (isHeavyAnimating() && !shouldForceOnHeavyAnimation) || (getIsHeavyAnimating() && !shouldForceOnHeavyAnimation)
) { ) {
return; return;
} }
@ -252,7 +253,7 @@ const AnimatedSticker: FC<OwnProps> = ({
} }
}, [playAnimation, animation, tgsUrl]); }, [playAnimation, animation, tgsUrl]);
useHeavyAnimationCheck(pauseAnimation, playAnimation, !playKey || shouldForceOnHeavyAnimation); useHeavyAnimation(pauseAnimation, playAnimation, !playKey || shouldForceOnHeavyAnimation);
usePriorityPlaybackCheck(pauseAnimation, playAnimation, !playKey || forceAlways); usePriorityPlaybackCheck(pauseAnimation, playAnimation, !playKey || forceAlways);
// Pausing frame may not happen in background, // Pausing frame may not happen in background,
// so we need to make sure it happens right after focusing, // 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) { function isFrozen(forceAlways = false, forceOnHeavyAnimation = false) {
if (forceAlways) return false; if (forceAlways) return false;
return (!forceOnHeavyAnimation && isHeavyAnimating()) || isPriorityPlaybackActive() || isBackgroundModeActive(); return (!forceOnHeavyAnimation && getIsHeavyAnimating()) || isPriorityPlaybackActive() || isBackgroundModeActive();
} }

View File

@ -9,7 +9,7 @@ import { preloadImage } from '../../../util/files';
import { REM } from '../helpers/mediaDimensions'; import { REM } from '../helpers/mediaDimensions';
import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener'; import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener';
import { useThrottleForHeavyAnimation } from '../../../hooks/useHeavyAnimationCheck'; import { useThrottleForHeavyAnimation } from '../../../hooks/useHeavyAnimation';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';

View File

@ -1,5 +1,6 @@
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
beginHeavyAnimation,
memo, useEffect, useMemo, useRef, useState, memo, useEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
@ -22,7 +23,6 @@ import { waitForTransitionEnd } from '../../../util/cssAnimationEndListeners';
import { IS_TOUCH_ENV } from '../../../util/windowEnvironment'; import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import { dispatchHeavyAnimationEvent } from '../../../hooks/useHeavyAnimationCheck';
import useHistoryBack from '../../../hooks/useHistoryBack'; import useHistoryBack from '../../../hooks/useHistoryBack';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll'; import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver'; import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver';
@ -148,8 +148,8 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
requestNextMutation(() => { requestNextMutation(() => {
if (!ref.current) return; if (!ref.current) return;
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent(); const endHeavyAnimation = beginHeavyAnimation();
waitForTransitionEnd(ref.current, dispatchHeavyAnimationStop); waitForTransitionEnd(ref.current, endHeavyAnimation);
onOpenAnimationStart?.(); onOpenAnimationStart?.();

View File

@ -1,6 +1,7 @@
import '../../global/actions/all'; import '../../global/actions/all';
import React, { import React, {
beginHeavyAnimation,
memo, useEffect, useLayoutEffect, memo, useEffect, useLayoutEffect,
useRef, useState, useRef, useState,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
@ -42,7 +43,6 @@ import useInterval from '../../hooks/schedulers/useInterval';
import useTimeout from '../../hooks/schedulers/useTimeout'; import useTimeout from '../../hooks/schedulers/useTimeout';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import usePreventPinchZoomGesture from '../../hooks/usePreventPinchZoomGesture'; import usePreventPinchZoomGesture from '../../hooks/usePreventPinchZoomGesture';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
@ -447,10 +447,10 @@ const Main = ({
}); });
} }
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent(); const endHeavyAnimation = beginHeavyAnimation();
waitForTransitionEnd(document.getElementById('MiddleColumn')!, () => { waitForTransitionEnd(document.getElementById('MiddleColumn')!, () => {
dispatchHeavyAnimationEnd(); endHeavyAnimation();
willAnimateLeftColumnRef.current = false; willAnimateLeftColumnRef.current = false;
forceUpdate(); forceUpdate();
}); });
@ -480,10 +480,10 @@ const Main = ({
willAnimateRightColumnRef.current = true; willAnimateRightColumnRef.current = true;
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent(); const endHeavyAnimation = beginHeavyAnimation();
waitForTransitionEnd(document.getElementById('RightColumn')!, () => { waitForTransitionEnd(document.getElementById('RightColumn')!, () => {
dispatchHeavyAnimationEnd(); endHeavyAnimation();
willAnimateRightColumnRef.current = false; willAnimateRightColumnRef.current = false;
forceUpdate(); forceUpdate();
setIsNarrowMessageList(isRightColumnOpen); setIsNarrowMessageList(isRightColumnOpen);

View File

@ -1,4 +1,5 @@
import React, { import React, {
beginHeavyAnimation,
memo, useEffect, useMemo, useRef, memo, useEffect, useMemo, useRef,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global'; import { getActions, withGlobal } from '../../global';
@ -40,7 +41,6 @@ import useAppLayout from '../../hooks/useAppLayout';
import useElectronDrag from '../../hooks/useElectronDrag'; import useElectronDrag from '../../hooks/useElectronDrag';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import { exitPictureInPictureIfNeeded, usePictureInPictureSignal } from '../../hooks/usePictureInPicture'; import { exitPictureInPictureIfNeeded, usePictureInPictureSignal } from '../../hooks/usePictureInPicture';
@ -216,12 +216,12 @@ const MediaViewer = ({
useEffect(() => { useEffect(() => {
if (isGhostAnimation && isOpen && (shouldAnimateOpening || !prevItem)) { 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); animateOpening(hasFooter, origin!, bestImageData!, dimensions!, isVideo, message, mediaIndex);
} }
if (isGhostAnimation && !isOpen && prevItem) { if (isGhostAnimation && !isOpen && prevItem) {
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY); beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
animateClosing(prevOrigin!, prevBestImageData!, prevMessage, prevItem?.mediaIndex); animateClosing(prevOrigin!, prevBestImageData!, prevMessage, prevItem?.mediaIndex);
} }
}, [ }, [

View File

@ -1,5 +1,6 @@
import type { FC } from '../../lib/teact/teact'; import type { FC } from '../../lib/teact/teact';
import React, { import React, {
beginHeavyAnimation,
memo, useEffect, useLayoutEffect, useRef, memo, useEffect, useLayoutEffect, useRef,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global'; import { getActions, withGlobal } from '../../global';
@ -13,7 +14,6 @@ import buildClassName from '../../util/buildClassName';
import { IS_ANDROID } from '../../util/windowEnvironment'; import { IS_ANDROID } from '../../util/windowEnvironment';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia'; import useMedia from '../../hooks/useMedia';
@ -74,11 +74,11 @@ const EmojiInteractionAnimation: FC<OwnProps & StateProps> = ({
}, [handleCancelAnimation]); }, [handleCancelAnimation]);
useLayoutEffect(() => { useLayoutEffect(() => {
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent(); const endHeavyAnimation = beginHeavyAnimation();
timeoutRef.current = setTimeout(() => { timeoutRef.current = setTimeout(() => {
stop(); stop();
dispatchHeavyAnimationStop(); endHeavyAnimation();
}, PLAYING_DURATION); }, PLAYING_DURATION);
}, [stop]); }, [stop]);

View File

@ -1,5 +1,6 @@
import type { FC } from '../../lib/teact/teact'; import type { FC } from '../../lib/teact/teact';
import React, { import React, {
beginHeavyAnimation,
memo, memo,
useEffect, useEffect,
useMemo, useMemo,
@ -66,7 +67,6 @@ import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
import useInterval from '../../hooks/schedulers/useInterval'; import useInterval from '../../hooks/schedulers/useInterval';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps'; import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
import useNativeCopySelectedMessages from '../../hooks/useNativeCopySelectedMessages'; import useNativeCopySelectedMessages from '../../hooks/useNativeCopySelectedMessages';
@ -629,7 +629,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
useEffectWithPrevDeps(([prevIsSelectModeActive]) => { useEffectWithPrevDeps(([prevIsSelectModeActive]) => {
if (prevIsSelectModeActive !== undefined) { if (prevIsSelectModeActive !== undefined) {
dispatchHeavyAnimationEvent(SELECT_MODE_ANIMATION_DURATION + ANIMATION_END_DELAY); beginHeavyAnimation(SELECT_MODE_ANIMATION_DURATION + ANIMATION_END_DELAY);
} }
}, [isSelectModeActive]); }, [isSelectModeActive]);

View File

@ -1,6 +1,6 @@
import type { RefObject } from 'react'; import type { RefObject } from 'react';
import type { FC } from '../../lib/teact/teact'; 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 { getActions } from '../../global';
import type { MessageListType } from '../../global/types'; import type { MessageListType } from '../../global/types';
@ -25,7 +25,6 @@ import { isAlbum } from './helpers/groupMessages';
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur'; import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
import useDerivedSignal from '../../hooks/useDerivedSignal'; import useDerivedSignal from '../../hooks/useDerivedSignal';
import { getIsHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import useMessageObservers from './hooks/useMessageObservers'; import useMessageObservers from './hooks/useMessageObservers';

View File

@ -1,6 +1,7 @@
import type { ChangeEvent, RefObject } from 'react'; import type { ChangeEvent, RefObject } from 'react';
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
getIsHeavyAnimating,
memo, useEffect, useLayoutEffect, memo, useEffect, useLayoutEffect,
useRef, useState, useRef, useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
@ -28,7 +29,6 @@ import { isSelectionInsideInput } from './helpers/selection';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useDerivedState from '../../../hooks/useDerivedState'; import useDerivedState from '../../../hooks/useDerivedState';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import { isHeavyAnimating } from '../../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import useInputCustomEmojis from './hooks/useInputCustomEmojis'; import useInputCustomEmojis from './hooks/useInputCustomEmojis';
@ -265,7 +265,7 @@ const MessageInput: FC<OwnProps & StateProps> = ({
return; return;
} }
if (isHeavyAnimating()) { if (getIsHeavyAnimating()) {
setTimeout(focusInput, FOCUS_DELAY_MS); setTimeout(focusInput, FOCUS_DELAY_MS);
return; return;
} }

View File

@ -1,11 +1,7 @@
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
memo, beginHeavyAnimation,
useCallback, memo, useCallback, useEffect, useMemo, useRef, useState,
useEffect,
useMemo,
useRef,
useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
@ -126,7 +122,6 @@ import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
import useEnsureMessage from '../../../hooks/useEnsureMessage'; import useEnsureMessage from '../../../hooks/useEnsureMessage';
import useEnsureStory from '../../../hooks/useEnsureStory'; import useEnsureStory from '../../../hooks/useEnsureStory';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import { dispatchHeavyAnimationEvent } from '../../../hooks/useHeavyAnimationCheck';
import { useOnIntersect } from '../../../hooks/useIntersectionObserver'; import { useOnIntersect } from '../../../hooks/useIntersectionObserver';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
@ -832,7 +827,7 @@ const Message: FC<OwnProps & StateProps> = ({
const container = entry.target.closest<HTMLDivElement>('.MessageList'); const container = entry.target.closest<HTMLDivElement>('.MessageList');
if (!container) return; if (!container) return;
dispatchHeavyAnimationEvent(RESIZE_ANIMATION_DURATION); beginHeavyAnimation(RESIZE_ANIMATION_DURATION);
const resizeDiff = newHeight - lastHeight; const resizeDiff = newHeight - lastHeight;
const { offsetHeight, scrollHeight, scrollTop } = container; const { offsetHeight, scrollHeight, scrollTop } = container;

View File

@ -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 { requestMeasure } from '../../../../lib/fasterdom/fasterdom';
import useHeavyAnimationCheck, { isHeavyAnimating } from '../../../../hooks/useHeavyAnimationCheck'; import useHeavyAnimation from '../../../../hooks/useHeavyAnimation';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../../../hooks/usePriorityPlaybackCheck'; import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../../../hooks/usePriorityPlaybackCheck';
import useBackgroundMode, { isBackgroundModeActive } from '../../../../hooks/window/useBackgroundMode'; import useBackgroundMode, { isBackgroundModeActive } from '../../../../hooks/window/useBackgroundMode';
@ -26,7 +26,7 @@ export default function useVideoAutoPause(
}); });
useBackgroundMode(pause, unfreezePlayingOnRaf, !canPlay || isPriority); useBackgroundMode(pause, unfreezePlayingOnRaf, !canPlay || isPriority);
useHeavyAnimationCheck(pause, unfreezePlaying, !canPlay || isPriority); useHeavyAnimation(pause, unfreezePlaying, !canPlay || isPriority);
usePriorityPlaybackCheck(pause, unfreezePlaying, !canPlay || isPriority); usePriorityPlaybackCheck(pause, unfreezePlaying, !canPlay || isPriority);
const handlePlaying = useLastCallback(() => { const handlePlaying = useLastCallback(() => {
@ -81,5 +81,5 @@ function usePlayPause(mediaRef: React.RefObject<HTMLMediaElement>) {
} }
function isFrozen() { function isFrozen() {
return isHeavyAnimating() || isPriorityPlaybackActive() || isBackgroundModeActive(); return getIsHeavyAnimating() || isPriorityPlaybackActive() || isBackgroundModeActive();
} }

View File

@ -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 { getActions, withGlobal } from '../../global';
import type { ApiChat, ApiUser } from '../../api/types'; 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 { selectIsForumPanelOpen, selectPerformanceSettingsValue, selectTabState } from '../../global/selectors';
import { animateClosing, animateOpening, ANIMATION_DURATION } from './helpers/ribbonAnimation'; import { animateClosing, animateOpening, ANIMATION_DURATION } from './helpers/ribbonAnimation';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useStoryPreloader from './hooks/useStoryPreloader'; import useStoryPreloader from './hooks/useStoryPreloader';
@ -98,10 +99,10 @@ function StoryToggler({
useEffect(() => { useEffect(() => {
if (!withAnimation || isForumPanelOpen) return; if (!withAnimation || isForumPanelOpen) return;
if (isVisible) { if (isVisible) {
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY); beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
animateClosing(isArchived); animateClosing(isArchived);
} else { } else {
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY); beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
animateOpening(isArchived); animateOpening(isArchived);
} }
}, [isArchived, isVisible, withAnimation, isForumPanelOpen]); }, [isArchived, isVisible, withAnimation, isForumPanelOpen]);

View File

@ -1,4 +1,5 @@
import React, { import React, {
beginHeavyAnimation,
memo, useCallback, useEffect, useState, memo, useCallback, useEffect, useState,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global'; import { getActions, withGlobal } from '../../global';
@ -19,7 +20,6 @@ import { disableDirectTextInput, enableDirectTextInput } from '../../util/direct
import { animateClosing, animateOpening } from './helpers/ghostAnimation'; import { animateClosing, animateOpening } from './helpers/ghostAnimation';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck'; import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
@ -117,11 +117,11 @@ function StoryViewer({
useEffect(() => { useEffect(() => {
if (isGhostAnimation && !isPrevOpen && isOpen && peerId && thumbnail && origin !== undefined) { 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); animateOpening(peerId, origin, thumbnail, bestImageData, slideSizes.activeSlide);
} }
if (isGhostAnimation && isPrevOpen && !isOpen && prevPeerId && prevBestImageData && prevOrigin !== undefined) { if (isGhostAnimation && isPrevOpen && !isOpen && prevPeerId && prevBestImageData && prevOrigin !== undefined) {
dispatchHeavyAnimationEvent(ANIMATION_DURATION + ANIMATION_END_DELAY); beginHeavyAnimation(ANIMATION_DURATION + ANIMATION_END_DELAY);
animateClosing(prevPeerId, prevOrigin, prevBestImageData); animateClosing(prevPeerId, prevOrigin, prevBestImageData);
} }
}, [ }, [

View File

@ -1,4 +1,5 @@
import React, { import React, {
beginHeavyAnimation,
type FC, memo, useEffect, useRef, type FC, memo, useEffect, useRef,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
@ -11,7 +12,6 @@ import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMe
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation'; import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
@ -100,7 +100,7 @@ const Menu: FC<OwnProps> = ({
useEffectWithPrevDeps(([prevIsOpen]) => { useEffectWithPrevDeps(([prevIsOpen]) => {
if (isOpen || (!isOpen && prevIsOpen === true)) { if (isOpen || (!isOpen && prevIsOpen === true)) {
dispatchHeavyAnimationEvent(ANIMATION_DURATION); beginHeavyAnimation(ANIMATION_DURATION);
} }
}, [isOpen]); }, [isOpen]);

View File

@ -1,5 +1,5 @@
import type { FC, TeactNode } from '../../lib/teact/teact'; 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'; import type { TextPart } from '../../types';
@ -9,7 +9,6 @@ import { disableDirectTextInput, enableDirectTextInput } from '../../util/direct
import freezeWhenClosed from '../../util/hoc/freezeWhenClosed'; import freezeWhenClosed from '../../util/hoc/freezeWhenClosed';
import trapFocus from '../../util/trapFocus'; import trapFocus from '../../util/trapFocus';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps'; import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
@ -110,7 +109,7 @@ const Modal: FC<OwnProps> = ({
document.body.classList.toggle('has-open-dialog', Boolean(isOpen)); document.body.classList.toggle('has-open-dialog', Boolean(isOpen));
if (isOpen || (!isOpen && prevIsOpen !== undefined)) { if (isOpen || (!isOpen && prevIsOpen !== undefined)) {
dispatchHeavyAnimationEvent(ANIMATION_DURATION); beginHeavyAnimation(ANIMATION_DURATION);
} }
return () => { return () => {

View File

@ -1,5 +1,7 @@
import type { RefObject } from 'react'; 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 { import {
addExtraClass, removeExtraClass, setExtraStyles, toggleExtraClass, addExtraClass, removeExtraClass, setExtraStyles, toggleExtraClass,
} from '../../lib/teact/teact-dom'; } from '../../lib/teact/teact-dom';
@ -14,7 +16,6 @@ import { omit } from '../../util/iteratees';
import { allowSwipeControlForTransition } from '../../util/swipeController'; import { allowSwipeControlForTransition } from '../../util/swipeController';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import './Transition.scss'; import './Transition.scss';
@ -233,7 +234,7 @@ function Transition({
}); });
isAnimatingRef.current = true; isAnimatingRef.current = true;
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent(); const endHeavyAnimation = beginHeavyAnimation();
onStart?.(); onStart?.();
toggleExtraClass(container, `Transition-${name}`, !isBackwards); toggleExtraClass(container, `Transition-${name}`, !isBackwards);
@ -245,7 +246,7 @@ function Transition({
requestMutation(() => { requestMutation(() => {
if (activeKey !== currentKeyRef.current) { if (activeKey !== currentKeyRef.current) {
dispatchHeavyAnimationStop(); endHeavyAnimation();
return; return;
} }
@ -269,7 +270,7 @@ function Transition({
} }
onStop?.(); onStop?.();
dispatchHeavyAnimationStop(); endHeavyAnimation();
isAnimatingRef.current = false; isAnimatingRef.current = false;
cleanup(); cleanup();
@ -291,7 +292,7 @@ function Transition({
giveUpAnimationEnd(); giveUpAnimationEnd();
isSwipeJustCancelledRef.current = true; isSwipeJustCancelledRef.current = true;
onStop?.(); onStop?.();
dispatchHeavyAnimationStop(); endHeavyAnimation();
isAnimatingRef.current = false; isAnimatingRef.current = false;
}, },
); );
@ -424,7 +425,7 @@ function performSlideOptimized(
} }
isAnimatingRef.current = true; isAnimatingRef.current = true;
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent(); const endHeavyAnimation = beginHeavyAnimation();
onStart?.(); onStart?.();
toggleExtraClass(container, `Transition-${name}`, !isBackwards); toggleExtraClass(container, `Transition-${name}`, !isBackwards);
@ -473,7 +474,7 @@ function performSlideOptimized(
requestMutation(() => { requestMutation(() => {
if (activeKey !== currentKeyRef.current) { if (activeKey !== currentKeyRef.current) {
dispatchHeavyAnimationStop(); endHeavyAnimation();
return; return;
} }
@ -490,7 +491,7 @@ function performSlideOptimized(
} }
onStop?.(); onStop?.();
dispatchHeavyAnimationStop(); endHeavyAnimation();
isAnimatingRef.current = false; isAnimatingRef.current = false;
cleanup(); cleanup();

View File

@ -1,4 +1,5 @@
/* eslint-disable eslint-multitab-tt/no-immediate-global */ /* eslint-disable eslint-multitab-tt/no-immediate-global */
import { getIsHeavyAnimating, onFullyIdle } from '../lib/teact/teact';
import { addCallback, removeCallback } from '../lib/teact/teactn'; import { addCallback, removeCallback } from '../lib/teact/teactn';
import type { ApiAvailableReaction, ApiMessage } from '../api/types'; import type { ApiAvailableReaction, ApiMessage } from '../api/types';
@ -44,7 +45,6 @@ import {
} from './selectors'; } from './selectors';
import { getIsMobile } from '../hooks/useAppLayout'; import { getIsMobile } from '../hooks/useAppLayout';
import { isHeavyAnimating, onFullyIdle } from '../hooks/useHeavyAnimationCheck';
const UPDATE_THROTTLE = 5000; const UPDATE_THROTTLE = 5000;
@ -249,7 +249,7 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) {
function updateCache(force?: boolean) { function updateCache(force?: boolean) {
const global = getGlobal(); const global = getGlobal();
if (isRemovingCache || !isCaching || global.isLoggingOut || (!force && isHeavyAnimating())) { if (isRemovingCache || !isCaching || global.isLoggingOut || (!force && getIsHeavyAnimating())) {
return; return;
} }

View File

@ -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 useForceUpdate from './useForceUpdate';
import useHeavyAnimationCheck, { isHeavyAnimating } from './useHeavyAnimationCheck'; import useHeavyAnimation from './useHeavyAnimation';
import useRunDebounced from './useRunDebounced'; import useRunDebounced from './useRunDebounced';
import useSyncEffect from './useSyncEffect'; import useSyncEffect from './useSyncEffect';
@ -43,10 +45,10 @@ function useHeavyAnimationFreeze() {
isPending.current = false; isPending.current = false;
forceUpdate(); forceUpdate();
}, [forceUpdate]); }, [forceUpdate]);
useHeavyAnimationCheck(noop, handleUnfreeze); useHeavyAnimation(noop, handleUnfreeze);
return { return {
isFrozen: isHeavyAnimating(), isFrozen: getIsHeavyAnimating(),
updateWhenUnfrozen, updateWhenUnfrozen,
}; };
} }

View File

@ -1,26 +1,23 @@
import { import {
getIsHeavyAnimating,
useCallback, useEffect, useMemo, useRef, useCallback, useEffect, useMemo, useRef,
} from '../lib/teact/teact'; } from '../lib/teact/teact';
import { requestMeasure } from '../lib/fasterdom/fasterdom';
import { createCallbackManager } from '../util/callbacks'; import { createCallbackManager } from '../util/callbacks';
import { onIdle } from '../util/schedulers';
import { createSignal } from '../util/signals';
import useLastCallback from './useLastCallback'; import useLastCallback from './useLastCallback';
// Make sure to end even if end callback was not called (which was some hardly-reproducible bug) export const startCallbacks = createCallbackManager();
const AUTO_END_TIMEOUT = 1000; export const endCallbacks = createCallbackManager();
const startCallbacks = createCallbackManager(); getIsHeavyAnimating.subscribe(() => {
const endCallbacks = createCallbackManager(); if (getIsHeavyAnimating()) {
startCallbacks.runCallbacks();
} else {
endCallbacks.runCallbacks();
}
});
let counter = 0; export default function useHeavyAnimation(
const [getIsAnimating, setIsAnimating] = createSignal(false);
export const getIsHeavyAnimating = getIsAnimating;
export default function useHeavyAnimationCheck(
onStart?: AnyToVoidFunction, onStart?: AnyToVoidFunction,
onEnd?: AnyToVoidFunction, onEnd?: AnyToVoidFunction,
isDisabled = false, isDisabled = false,
@ -33,7 +30,7 @@ export default function useHeavyAnimationCheck(
return undefined; return undefined;
} }
if (getIsAnimating()) { if (getIsHeavyAnimating()) {
lastOnStart(); lastOnStart();
} }
@ -57,7 +54,7 @@ export function useThrottleForHeavyAnimation<T extends AnyToVoidFunction>(afterH
return useMemo(() => { return useMemo(() => {
return (...args: Parameters<T>) => { return (...args: Parameters<T>) => {
if (!isScheduledRef.current) { if (!isScheduledRef.current) {
if (!getIsAnimating()) { if (!getIsHeavyAnimating()) {
fnMemo(...args); fnMemo(...args);
return; return;
} }
@ -73,48 +70,3 @@ export function useThrottleForHeavyAnimation<T extends AnyToVoidFunction>(afterH
}; };
}, [fnMemo]); }, [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();
}
});
}

View File

@ -7,7 +7,7 @@ import { type CallbackManager, createCallbackManager } from '../util/callbacks';
import { import {
debounce, throttle, throttleWith, debounce, throttle, throttleWith,
} from '../util/schedulers'; } from '../util/schedulers';
import useHeavyAnimationCheck from './useHeavyAnimationCheck'; import useHeavyAnimation from './useHeavyAnimation';
import useLastCallback from './useLastCallback'; import useLastCallback from './useLastCallback';
type TargetCallback = (entry: IntersectionObserverEntry) => void; type TargetCallback = (entry: IntersectionObserverEntry) => void;
@ -71,7 +71,7 @@ export function useIntersectionObserver({
} }
}); });
useHeavyAnimationCheck(freeze, unfreeze); useHeavyAnimation(freeze, unfreeze);
useEffect(() => { useEffect(() => {
if (isDisabled) { if (isDisabled) {

View File

@ -1,7 +1,6 @@
import { useEffect, useSignal } from '../lib/teact/teact'; import { getIsHeavyAnimating, useEffect, useSignal } from '../lib/teact/teact';
import useDerivedState from './useDerivedState'; import useDerivedState from './useDerivedState';
import { getIsHeavyAnimating } from './useHeavyAnimationCheck';
export default function useMountAfterHeavyAnimation(hasIntersected: boolean) { export default function useMountAfterHeavyAnimation(hasIntersected: boolean) {
const [getNoHeavyAnimation, setNoHeavyAnimation] = useSignal(false); const [getNoHeavyAnimation, setNoHeavyAnimation] = useSignal(false);

View File

@ -1,8 +1,7 @@
import type { RefObject } from 'react'; 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 unloadVideo from '../util/browser/unloadVideo';
import { onFullyIdle } from './useHeavyAnimationCheck';
// Fix for memory leak when unmounting video element // Fix for memory leak when unmounting video element
export default function useVideoCleanup(videoRef: RefObject<HTMLVideoElement>, dependencies: any[]) { export default function useVideoCleanup(videoRef: RefObject<HTMLVideoElement>, dependencies: any[]) {

View 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();
}
});
}

View File

@ -9,6 +9,8 @@ import { throttleWith } from '../../util/schedulers';
import { createSignal, isSignal, type Signal } from '../../util/signals'; import { createSignal, isSignal, type Signal } from '../../util/signals';
import { requestMeasure, requestMutation } from '../fasterdom/fasterdom'; import { requestMeasure, requestMutation } from '../fasterdom/fasterdom';
export { getIsHeavyAnimating, beginHeavyAnimation, onFullyIdle } from './heavyAnimation';
export type Props = AnyLiteral; export type Props = AnyLiteral;
export type FC<P extends Props = any> = (props: P) => any; export type FC<P extends Props = any> = (props: P) => any;
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention

View File

@ -6,10 +6,9 @@ import { handleError } from '../../util/handleError';
import { orderBy } from '../../util/iteratees'; import { orderBy } from '../../util/iteratees';
import { throttleWithTickEnd } from '../../util/schedulers'; import { throttleWithTickEnd } from '../../util/schedulers';
import { requestMeasure } from '../fasterdom/fasterdom'; 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 useForceUpdate from '../../hooks/useForceUpdate';
import { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
import useUniqueId from '../../hooks/useUniqueId'; import useUniqueId from '../../hooks/useUniqueId';
export default React; export default React;
@ -75,7 +74,7 @@ let forceOnHeavyAnimation = true;
function runCallbacks() { function runCallbacks() {
if (forceOnHeavyAnimation) { if (forceOnHeavyAnimation) {
forceOnHeavyAnimation = false; forceOnHeavyAnimation = false;
} else if (isHeavyAnimating()) { } else if (getIsHeavyAnimating()) {
requestMeasure(runCallbacksThrottled); requestMeasure(runCallbacksThrottled);
return; return;
} }

View File

@ -1,3 +1,4 @@
import { beginHeavyAnimation } from '../lib/teact/teact';
import { getGlobal } from '../global'; import { getGlobal } from '../global';
import type { ScrollTargetPosition } from '../types'; import type { ScrollTargetPosition } from '../types';
@ -14,13 +15,11 @@ import { selectCanAnimateInterface } from '../global/selectors';
import { animateSingle, cancelSingleAnimation } from './animation'; import { animateSingle, cancelSingleAnimation } from './animation';
import { IS_ANDROID } from './windowEnvironment'; import { IS_ANDROID } from './windowEnvironment';
import { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';
type Params = Parameters<typeof createMutateFunction>; type Params = Parameters<typeof createMutateFunction>;
let isAnimating = false; let isAnimating = false;
let currentArgs: Parameters<typeof createMutateFunction> | undefined; let currentArgs: Parameters<typeof createMutateFunction> | undefined;
let onHeavyAnimationStop: NoneToVoidFunction | undefined; let onHeavyAnimationEnd: NoneToVoidFunction | undefined;
export default function animateScroll(...args: Params | [...Params, boolean]) { export default function animateScroll(...args: Params | [...Params, boolean]) {
currentArgs = args.slice(0, 8) as Params; currentArgs = args.slice(0, 8) as Params;
@ -127,9 +126,9 @@ function createMutateFunction(
isAnimating = true; isAnimating = true;
const prevOnHeavyAnimationStop = onHeavyAnimationStop; const prevOnHeavyAnimationEnd = onHeavyAnimationEnd;
onHeavyAnimationStop = dispatchHeavyAnimationEvent(); onHeavyAnimationEnd = beginHeavyAnimation();
prevOnHeavyAnimationStop?.(); prevOnHeavyAnimationEnd?.();
animateSingle(() => { animateSingle(() => {
const t = Math.min((Date.now() - startAt) / duration, 1); const t = Math.min((Date.now() - startAt) / duration, 1);
@ -143,8 +142,8 @@ function createMutateFunction(
if (!isAnimating) { if (!isAnimating) {
currentArgs = undefined; currentArgs = undefined;
onHeavyAnimationStop!(); onHeavyAnimationEnd!();
onHeavyAnimationStop = undefined; onHeavyAnimationEnd = undefined;
} }
return isAnimating; return isAnimating;

View File

@ -1,3 +1,4 @@
import { onFullyIdle } from '../lib/teact/teact';
import { addCallback } from '../lib/teact/teactn'; import { addCallback } from '../lib/teact/teactn';
import { addActionHandler, getGlobal } from '../global'; import { addActionHandler, getGlobal } from '../global';
@ -23,8 +24,6 @@ import { createCallbackManager } from './callbacks';
import { areSortedArraysEqual, unique } from './iteratees'; import { areSortedArraysEqual, unique } from './iteratees';
import { throttle } from './schedulers'; import { throttle } from './schedulers';
import { onFullyIdle } from '../hooks/useHeavyAnimationCheck';
interface FolderSummary { interface FolderSummary {
id: number; id: number;
listIds?: Set<string>; listIds?: Set<string>;

View File

@ -1,4 +1,5 @@
/* eslint-disable eslint-multitab-tt/set-global-only-variable */ /* eslint-disable eslint-multitab-tt/set-global-only-variable */
import { onFullyIdle } from '../lib/teact/teact';
import { addCallback } from '../lib/teact/teactn'; import { addCallback } from '../lib/teact/teactn';
import { getActions, getGlobal, setGlobal } from '../global'; import { getActions, getGlobal, setGlobal } from '../global';
@ -24,8 +25,6 @@ import { getCurrentTabId, signalPasscodeHash, subscribeToTokenDied } from './est
import { omit } from './iteratees'; import { omit } from './iteratees';
import { IS_MULTITAB_SUPPORTED } from './windowEnvironment'; import { IS_MULTITAB_SUPPORTED } from './windowEnvironment';
import { onFullyIdle } from '../hooks/useHeavyAnimationCheck';
type BroadcastChannelRefreshLangpack = { type BroadcastChannelRefreshLangpack = {
type: 'langpackRefresh'; type: 'langpackRefresh';
langCode: string; langCode: string;