Fix incorrect callback referencing

This commit is contained in:
Alexander Zinchuk 2023-04-26 21:15:08 +04:00
parent 485d52cab3
commit 70847a933e
6 changed files with 56 additions and 39 deletions

View File

@ -62,10 +62,6 @@ const useDraft = (
}
}, [chatId, threadId, isEditing, lastSyncTime, getHtml, saveDraft, clearDraft]);
const forceUpdateDraft = useCallback(() => {
updateDraft(undefined, true);
}, [updateDraft]);
const updateDraftRef = useStateRef(updateDraft);
const runDebouncedForSaveDraft = useRunDebounced(DRAFT_DEBOUNCE, true, undefined, [chatId, threadId]);
@ -138,6 +134,10 @@ const useDraft = (
});
}, [chatIdRef, getHtml, runDebouncedForSaveDraft, threadIdRef, updateDraftRef]);
function forceUpdateDraft() {
updateDraft(undefined, true);
}
useBackgroundMode(forceUpdateDraft);
useBeforeUnload(forceUpdateDraft);
};

View File

@ -1,6 +1,7 @@
import { useEffect } from '../lib/teact/teact';
import { createCallbackManager } from '../util/callbacks';
import { useLastCallback } from './useLastCallback';
const blurCallbacks = createCallbackManager();
const focusCallbacks = createCallbackManager();
@ -26,33 +27,26 @@ export default function useBackgroundMode(
onFocus?: AnyToVoidFunction,
isDisabled = false,
) {
const lastOnBlur = useLastCallback(onBlur);
const lastOnFocus = useLastCallback(onFocus);
useEffect(() => {
if (isDisabled) {
return undefined;
}
if (!isFocused) {
onBlur?.();
lastOnBlur();
}
if (onBlur) {
blurCallbacks.addCallback(onBlur);
}
if (onFocus) {
focusCallbacks.addCallback(onFocus);
}
blurCallbacks.addCallback(lastOnBlur);
focusCallbacks.addCallback(lastOnFocus);
return () => {
if (onFocus) {
focusCallbacks.removeCallback(onFocus);
}
if (onBlur) {
blurCallbacks.removeCallback(onBlur);
}
focusCallbacks.removeCallback(lastOnFocus);
blurCallbacks.removeCallback(lastOnBlur);
};
}, [isDisabled, onBlur, onFocus]);
}, [isDisabled, lastOnBlur, lastOnFocus]);
}
export function isBackgroundModeActive() {

View File

@ -2,8 +2,10 @@ import { useEffect } from '../lib/teact/teact';
import { onBeforeUnload } from '../util/schedulers';
import { useLastCallback } from './useLastCallback';
export default function useBeforeUnload(callback: AnyToVoidFunction) {
useEffect(() => {
return onBeforeUnload(callback);
}, [callback]);
const lastCallback = useLastCallback(callback);
useEffect(() => onBeforeUnload(lastCallback), [lastCallback]);
}

View File

@ -1,6 +1,9 @@
import { useEffect } from '../lib/teact/teact';
import { createCallbackManager } from '../util/callbacks';
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;
@ -11,27 +14,30 @@ let timeout: number | undefined;
let isAnimating = false;
const useHeavyAnimationCheck = (
handleAnimationStart: AnyToVoidFunction,
handleAnimationEnd: AnyToVoidFunction,
onStart?: AnyToVoidFunction,
onEnd?: AnyToVoidFunction,
isDisabled = false,
) => {
const lastOnStart = useLastCallback(onStart);
const lastOnEnd = useLastCallback(onEnd);
useEffect(() => {
if (isDisabled) {
return undefined;
}
if (isAnimating) {
handleAnimationStart();
lastOnStart();
}
startCallbacks.addCallback(handleAnimationStart);
endCallbacks.addCallback(handleAnimationEnd);
startCallbacks.addCallback(lastOnStart);
endCallbacks.addCallback(lastOnEnd);
return () => {
endCallbacks.removeCallback(handleAnimationEnd);
startCallbacks.removeCallback(handleAnimationStart);
endCallbacks.removeCallback(lastOnEnd);
startCallbacks.removeCallback(lastOnStart);
};
}, [isDisabled, handleAnimationEnd, handleAnimationStart]);
}, [isDisabled, lastOnEnd, lastOnStart]);
};
export function isHeavyAnimating() {

View File

@ -0,0 +1,9 @@
import { useCallback } from '../lib/teact/teact';
import { useStateRef } from './useStateRef';
export function useLastCallback<T extends AnyFunction>(callback?: T) {
const ref = useStateRef(callback);
return useCallback((...args: Parameters<T>) => ref.current?.(...args), [ref]) as T;
}

View File

@ -1,6 +1,9 @@
import { useEffect } from '../lib/teact/teact';
import { createCallbackManager } from '../util/callbacks';
import { useLastCallback } from './useLastCallback';
const startCallbacks = createCallbackManager();
const endCallbacks = createCallbackManager();
@ -8,27 +11,30 @@ let timeout: number | undefined;
let isActive = false;
const usePriorityPlaybackCheck = (
handleAnimationStart: AnyToVoidFunction,
handleAnimationEnd: AnyToVoidFunction,
onStart?: AnyToVoidFunction,
onEnd?: AnyToVoidFunction,
isDisabled = false,
) => {
const lastOnStart = useLastCallback(onStart);
const lastOnEnd = useLastCallback(onEnd);
useEffect(() => {
if (isDisabled) {
return undefined;
}
if (isActive) {
handleAnimationStart();
lastOnStart();
}
startCallbacks.addCallback(handleAnimationStart);
endCallbacks.addCallback(handleAnimationEnd);
startCallbacks.addCallback(lastOnStart);
endCallbacks.addCallback(lastOnEnd);
return () => {
endCallbacks.removeCallback(handleAnimationEnd);
startCallbacks.removeCallback(handleAnimationStart);
endCallbacks.removeCallback(lastOnEnd);
startCallbacks.removeCallback(lastOnStart);
};
}, [isDisabled, handleAnimationEnd, handleAnimationStart]);
}, [isDisabled, lastOnStart, lastOnEnd]);
};
export function isPriorityPlaybackActive() {