Message List: Fix polling error (#4340)

This commit is contained in:
Alexander Zinchuk 2024-03-08 12:48:40 +01:00
parent 58edfa2a2c
commit 00a98971b3
21 changed files with 64 additions and 71 deletions

View File

@ -19,8 +19,8 @@ import { fastRaf } from '../../../util/schedulers';
import { IS_CANVAS_FILTER_SUPPORTED } from '../../../util/windowEnvironment'; import { IS_CANVAS_FILTER_SUPPORTED } from '../../../util/windowEnvironment';
import formatGroupCallVolume from './helpers/formatGroupCallVolume'; import formatGroupCallVolume from './helpers/formatGroupCallVolume';
import useInterval from '../../../hooks/schedulers/useInterval';
import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers'; import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
import useInterval from '../../../hooks/useInterval';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useMenuPosition from '../../../hooks/useMenuPosition'; import useMenuPosition from '../../../hooks/useMenuPosition';

View File

@ -23,10 +23,10 @@ import {
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets'; import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
import useInterval from '../../../hooks/schedulers/useInterval';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useForceUpdate from '../../../hooks/useForceUpdate'; import useForceUpdate from '../../../hooks/useForceUpdate';
import useInterval from '../../../hooks/useInterval';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import AnimatedIcon from '../../common/AnimatedIcon'; import AnimatedIcon from '../../common/AnimatedIcon';
@ -137,9 +137,7 @@ const PhoneCall: FC<StateProps> = ({
const forceUpdate = useForceUpdate(); const forceUpdate = useForceUpdate();
useInterval(() => { useInterval(forceUpdate, isConnected ? 1000 : undefined);
forceUpdate();
}, isConnected ? 1000 : undefined);
const callStatus = useMemo(() => { const callStatus = useMemo(() => {
const state = phoneCall?.state; const state = phoneCall?.state;

View File

@ -105,12 +105,13 @@ import { getPeerColorClass } from './helpers/peerColor';
import renderText from './helpers/renderText'; import renderText from './helpers/renderText';
import { getTextWithEntitiesAsHtml } from './helpers/renderTextWithEntities'; import { getTextWithEntitiesAsHtml } from './helpers/renderTextWithEntities';
import useInterval from '../../hooks/schedulers/useInterval';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers'; import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
import useDerivedState from '../../hooks/useDerivedState'; import useDerivedState from '../../hooks/useDerivedState';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import useGetSelectionRange from '../../hooks/useGetSelectionRange'; import useGetSelectionRange from '../../hooks/useGetSelectionRange';
import useInterval from '../../hooks/useInterval';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
@ -120,7 +121,6 @@ import useShowTransition from '../../hooks/useShowTransition';
import useSignal from '../../hooks/useSignal'; import useSignal from '../../hooks/useSignal';
import { useStateRef } from '../../hooks/useStateRef'; import { useStateRef } from '../../hooks/useStateRef';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import useTimeout from '../../hooks/useTimeout';
import useAttachmentModal from '../middle/composer/hooks/useAttachmentModal'; import useAttachmentModal from '../middle/composer/hooks/useAttachmentModal';
import useBotCommandTooltip from '../middle/composer/hooks/useBotCommandTooltip'; import useBotCommandTooltip from '../middle/composer/hooks/useBotCommandTooltip';
import useClipboardPaste from '../middle/composer/hooks/useClipboardPaste'; import useClipboardPaste from '../middle/composer/hooks/useClipboardPaste';

View File

@ -10,9 +10,9 @@ import buildClassName from '../../util/buildClassName';
import stopEvent from '../../util/stopEvent'; import stopEvent from '../../util/stopEvent';
import { IS_TOUCH_ENV } from '../../util/windowEnvironment'; import { IS_TOUCH_ENV } from '../../util/windowEnvironment';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useTimeout from '../../hooks/useTimeout';
import Button from '../ui/Button'; import Button from '../ui/Button';

View File

@ -4,9 +4,9 @@ import React, { memo, useCallback } from '../../lib/teact/teact';
import { STICKER_SIZE_AUTH, STICKER_SIZE_AUTH_MOBILE, STICKER_SIZE_TWO_FA } from '../../config'; import { STICKER_SIZE_AUTH, STICKER_SIZE_AUTH_MOBILE, STICKER_SIZE_TWO_FA } from '../../config';
import { LOCAL_TGS_URLS } from './helpers/animatedAssets'; import { LOCAL_TGS_URLS } from './helpers/animatedAssets';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import useTimeout from '../../hooks/useTimeout';
import AnimatedSticker from './AnimatedSticker'; import AnimatedSticker from './AnimatedSticker';

View File

@ -8,10 +8,10 @@ import { EMOJI_STATUS_LOOP_LIMIT } from '../../../config';
import { selectUser } from '../../../global/selectors'; import { selectUser } from '../../../global/selectors';
import { getServerTimeOffset } from '../../../util/serverTime'; import { getServerTimeOffset } from '../../../util/serverTime';
import useTimeout from '../../../hooks/schedulers/useTimeout';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useEffectWithPrevDeps from '../../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../../hooks/useEffectWithPrevDeps';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useTimeout from '../../../hooks/useTimeout';
import CustomEmoji from '../../common/CustomEmoji'; import CustomEmoji from '../../common/CustomEmoji';
import PremiumIcon from '../../common/PremiumIcon'; import PremiumIcon from '../../common/PremiumIcon';

View File

@ -9,7 +9,7 @@ import { MAIN_THREAD_ID } from '../../api/types';
import { getCanPostInChat } from '../../global/helpers'; import { getCanPostInChat } from '../../global/helpers';
import { selectChat, selectChatFullInfo } from '../../global/selectors'; import { selectChat, selectChatFullInfo } from '../../global/selectors';
import useInterval from '../../hooks/useInterval'; import useInterval from '../../hooks/schedulers/useInterval';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useSendMessageAction from '../../hooks/useSendMessageAction'; import useSendMessageAction from '../../hooks/useSendMessageAction';

View File

@ -9,10 +9,10 @@ import type { GlobalState } from '../../global/types';
import { decryptSession } from '../../util/passcode'; import { decryptSession } from '../../util/passcode';
import { LOCAL_TGS_URLS } from '../common/helpers/animatedAssets'; import { LOCAL_TGS_URLS } from '../common/helpers/animatedAssets';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useTimeout from '../../hooks/useTimeout';
import AnimatedIconWithPreview from '../common/AnimatedIconWithPreview'; import AnimatedIconWithPreview from '../common/AnimatedIconWithPreview';
import PasswordForm from '../common/PasswordForm'; import PasswordForm from '../common/PasswordForm';

View File

@ -49,15 +49,15 @@ import { parseInitialLocationHash, parseLocationHash } from '../../util/routing'
import updateIcon from '../../util/updateIcon'; import updateIcon from '../../util/updateIcon';
import { IS_ANDROID, IS_ELECTRON } from '../../util/windowEnvironment'; import { IS_ANDROID, IS_ELECTRON } from '../../util/windowEnvironment';
import useInterval from '../../hooks/schedulers/useInterval';
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 { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useInterval from '../../hooks/useInterval';
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';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import useTimeout from '../../hooks/useTimeout';
import useBackgroundMode from '../../hooks/window/useBackgroundMode'; import useBackgroundMode from '../../hooks/window/useBackgroundMode';
import useBeforeUnload from '../../hooks/window/useBeforeUnload'; import useBeforeUnload from '../../hooks/window/useBeforeUnload';
import { useFullscreenStatus } from '../../hooks/window/useFullscreen'; import { useFullscreenStatus } from '../../hooks/window/useFullscreen';

View File

@ -18,6 +18,7 @@ import { clamp, isBetween, round } from '../../util/math';
import { debounce } from '../../util/schedulers'; import { debounce } from '../../util/schedulers';
import { IS_IOS, IS_TOUCH_ENV } from '../../util/windowEnvironment'; import { IS_IOS, IS_TOUCH_ENV } from '../../util/windowEnvironment';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useDebouncedCallback from '../../hooks/useDebouncedCallback'; import useDebouncedCallback from '../../hooks/useDebouncedCallback';
import useDerivedState from '../../hooks/useDerivedState'; import useDerivedState from '../../hooks/useDerivedState';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
@ -25,7 +26,6 @@ import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useSignal from '../../hooks/useSignal'; import useSignal from '../../hooks/useSignal';
import { useSignalRef } from '../../hooks/useSignalRef'; import { useSignalRef } from '../../hooks/useSignalRef';
import useTimeout from '../../hooks/useTimeout';
import { useFullscreenStatus } from '../../hooks/window/useFullscreen'; import { useFullscreenStatus } from '../../hooks/window/useFullscreen';
import useWindowSize from '../../hooks/window/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import useControlsSignal from './hooks/useControlsSignal'; import useControlsSignal from './hooks/useControlsSignal';

View File

@ -62,9 +62,9 @@ import { debounce, onTickEnd } from '../../util/schedulers';
import { groupMessages } from './helpers/groupMessages'; import { groupMessages } from './helpers/groupMessages';
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur'; import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
import useInterval from '../../hooks/schedulers/useInterval';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'; import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useInterval from '../../hooks/useInterval';
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';
@ -276,13 +276,13 @@ const MessageList: FC<OwnProps & StateProps> = ({
const ids = messageIds.filter((id) => { const ids = messageIds.filter((id) => {
const message = messagesById[id]; const message = messagesById[id];
return message.reactions?.results.length && !message.content.action; return message && message.reactions?.results.length && !message.content.action;
}); });
if (!ids.length) return; if (!ids.length) return;
loadMessageReactions({ chatId, ids }); loadMessageReactions({ chatId, ids });
}, MESSAGE_REACTIONS_POLLING_INTERVAL); }, MESSAGE_REACTIONS_POLLING_INTERVAL, true);
useInterval(() => { useInterval(() => {
if (!messageIds || !messagesById || type === 'scheduled') { if (!messageIds || !messagesById || type === 'scheduled') {
@ -317,7 +317,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
if (!ids.length) return; if (!ids.length) return;
loadMessageViews({ chatId, ids }); loadMessageViews({ chatId, ids });
}, MESSAGE_COMMENTS_POLLING_INTERVAL); }, MESSAGE_COMMENTS_POLLING_INTERVAL, true);
const loadMoreAround = useMemo(() => { const loadMoreAround = useMemo(() => {
if (type !== 'thread') { if (type !== 'thread') {

View File

@ -9,7 +9,7 @@ import buildClassName from '../../../util/buildClassName';
import { formatMediaDuration } from '../../../util/dateFormat'; import { formatMediaDuration } from '../../../util/dateFormat';
import { formatCurrency } from '../../../util/formatCurrency'; import { formatCurrency } from '../../../util/formatCurrency';
import useInterval from '../../../hooks/useInterval'; import useInterval from '../../../hooks/schedulers/useInterval';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';

View File

@ -20,13 +20,13 @@ import {
} from '../../../util/map'; } from '../../../util/map';
import { getServerTime } from '../../../util/serverTime'; import { getServerTime } from '../../../util/serverTime';
import useInterval from '../../../hooks/schedulers/useInterval';
import useTimeout from '../../../hooks/schedulers/useTimeout';
import useForceUpdate from '../../../hooks/useForceUpdate'; import useForceUpdate from '../../../hooks/useForceUpdate';
import useInterval from '../../../hooks/useInterval';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
import usePrevious from '../../../hooks/usePrevious'; import usePrevious from '../../../hooks/usePrevious';
import useTimeout from '../../../hooks/useTimeout';
import Avatar from '../../common/Avatar'; import Avatar from '../../common/Avatar';
import Skeleton from '../../ui/placeholder/Skeleton'; import Skeleton from '../../ui/placeholder/Skeleton';

View File

@ -16,12 +16,12 @@ import buildClassName from '../../../util/buildClassName';
import { getAverageColor, rgb2hex } from '../../../util/colors'; import { getAverageColor, rgb2hex } from '../../../util/colors';
import { formatIntegerCompact } from '../../../util/textFormat'; import { formatIntegerCompact } from '../../../util/textFormat';
import useTimeout from '../../../hooks/schedulers/useTimeout';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useHorizontalScroll from '../../../hooks/useHorizontalScroll'; import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
import useTimeout from '../../../hooks/useTimeout';
import Avatar from '../../common/Avatar'; import Avatar from '../../common/Avatar';
import Icon from '../../common/Icon'; import Icon from '../../common/Icon';
@ -79,7 +79,7 @@ const SimilarChannels = ({
&& areSimilarChannelsPresent, && areSimilarChannelsPresent,
); );
useTimeout(() => setShoulRenderSkeleton(false), MAX_SKELETON_DELAY, []); useTimeout(() => setShoulRenderSkeleton(false), MAX_SKELETON_DELAY);
useEffect(() => { useEffect(() => {
if (shoulRenderSkeleton && similarChannels && shouldShowInChat) { if (shoulRenderSkeleton && similarChannels && shouldShowInChat) {

View File

@ -22,9 +22,9 @@ import { extractCurrentThemeParams, validateHexColor } from '../../../util/theme
import { callApi } from '../../../api/gramjs'; import { callApi } from '../../../api/gramjs';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
import useInterval from '../../../hooks/schedulers/useInterval';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useInterval from '../../../hooks/useInterval';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import usePrevious from '../../../hooks/usePrevious'; import usePrevious from '../../../hooks/usePrevious';

View File

@ -15,10 +15,10 @@ import { formatCountdown, MILLISECONDS_IN_DAY } from '../../../util/dateFormat';
import { getServerTime } from '../../../util/serverTime'; import { getServerTime } from '../../../util/serverTime';
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets'; import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
import useInterval from '../../../hooks/schedulers/useInterval';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useForceUpdate from '../../../hooks/useForceUpdate'; import useForceUpdate from '../../../hooks/useForceUpdate';
import useHistoryBack from '../../../hooks/useHistoryBack'; import useHistoryBack from '../../../hooks/useHistoryBack';
import useInterval from '../../../hooks/useInterval';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import AnimatedIcon from '../../common/AnimatedIcon'; import AnimatedIcon from '../../common/AnimatedIcon';
@ -92,9 +92,7 @@ const ManageInvites: FC<OwnProps & StateProps> = ({
)); ));
}, [exportedInvites]); }, [exportedInvites]);
const forceUpdate = useForceUpdate(); const forceUpdate = useForceUpdate();
useInterval(() => { useInterval(forceUpdate, hasDetailedCountdown ? 1000 : undefined);
forceUpdate();
}, hasDetailedCountdown ? 1000 : undefined);
const chatMainUsername = useMemo(() => chat && getMainUsername(chat), [chat]); const chatMainUsername = useMemo(() => chat && getMainUsername(chat), [chat]);
const primaryInvite = exportedInvites?.find(({ isPermanent }) => isPermanent); const primaryInvite = exportedInvites?.find(({ isPermanent }) => isPermanent);

View File

@ -3,8 +3,8 @@ import React, { type FC, memo, useEffect } from '../../lib/teact/teact';
import { formatMediaDuration } from '../../util/dateFormat'; import { formatMediaDuration } from '../../util/dateFormat';
import { getServerTime } from '../../util/serverTime'; import { getServerTime } from '../../util/serverTime';
import useInterval from '../../hooks/schedulers/useInterval';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import useInterval from '../../hooks/useInterval';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
type OwnProps = { type OwnProps = {

View File

@ -0,0 +1,20 @@
import { useEffect } from '../../lib/teact/teact';
import useLastCallback from '../useLastCallback';
function useInterval(callback: NoneToVoidFunction, delay?: number, noFirst = false) {
const savedCallback = useLastCallback(callback);
useEffect(() => {
if (delay === undefined) {
return undefined;
}
const id = setInterval(() => savedCallback(), delay);
if (!noFirst) savedCallback();
return () => clearInterval(id);
}, [delay, noFirst]);
}
export default useInterval;

View File

@ -0,0 +1,18 @@
import { useEffect } from '../../lib/teact/teact';
import useLastCallback from '../useLastCallback';
function useTimeout(callback: NoneToVoidFunction, delay?: number) {
const savedCallback = useLastCallback(callback);
useEffect(() => {
if (typeof delay !== 'number') {
return undefined;
}
const id = setTimeout(() => savedCallback(), delay);
return () => clearTimeout(id);
}, [delay]);
}
export default useTimeout;

View File

@ -1,22 +0,0 @@
import { useEffect, useLayoutEffect, useRef } from '../lib/teact/teact';
function useInterval(callback: NoneToVoidFunction, delay?: number, noFirst = false) {
const savedCallback = useRef(callback);
useLayoutEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
if (delay === undefined) {
return undefined;
}
const id = setInterval(() => savedCallback.current(), delay);
if (!noFirst) savedCallback.current();
return () => clearInterval(id);
}, [delay, noFirst]);
}
export default useInterval;

View File

@ -1,19 +0,0 @@
import { useEffect } from '../lib/teact/teact';
import useLastCallback from './useLastCallback';
function useTimeout(callback: () => void, delay?: number, dependencies: readonly any[] = []) {
const savedCallback = useLastCallback(callback);
useEffect(() => {
if (typeof delay !== 'number') {
return undefined;
}
const id = setTimeout(() => savedCallback(), delay);
return () => clearTimeout(id);
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
}, [delay, savedCallback, ...dependencies]);
}
export default useTimeout;