TeactN: Support forcing during heavy animation

This commit is contained in:
Alexander Zinchuk 2021-12-10 18:33:37 +01:00
parent 9c7dc01f86
commit e86c126a89
6 changed files with 29 additions and 22 deletions

View File

@ -118,7 +118,7 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
}, [displayedFolders, folderCountersById, lang]); }, [displayedFolders, folderCountersById, lang]);
const handleSwitchTab = useCallback((index: number) => { const handleSwitchTab = useCallback((index: number) => {
setActiveChatFolder(index); setActiveChatFolder(index, { forceOnHeavyAnimation: true });
}, [setActiveChatFolder]); }, [setActiveChatFolder]);
// Prevent `activeTab` pointing at non-existing folder after update // Prevent `activeTab` pointing at non-existing folder after update
@ -141,10 +141,10 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
selectorToPreventScroll: '.chat-list', selectorToPreventScroll: '.chat-list',
onSwipe: ((e, direction) => { onSwipe: ((e, direction) => {
if (direction === SwipeDirection.Left) { if (direction === SwipeDirection.Left) {
setActiveChatFolder(Math.min(activeChatFolder + 1, folderTabs.length - 1)); setActiveChatFolder(Math.min(activeChatFolder + 1, folderTabs.length - 1), { forceOnHeavyAnimation: true });
return true; return true;
} else if (direction === SwipeDirection.Right) { } else if (direction === SwipeDirection.Right) {
setActiveChatFolder(Math.max(0, activeChatFolder - 1)); setActiveChatFolder(Math.max(0, activeChatFolder - 1), { forceOnHeavyAnimation: true });
return true; return true;
} }
@ -161,7 +161,7 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
} }
}) : undefined), [activeChatFolder, setActiveChatFolder]); }) : undefined), [activeChatFolder, setActiveChatFolder]);
useHistoryBack(activeChatFolder !== 0, () => setActiveChatFolder(0)); useHistoryBack(activeChatFolder !== 0, () => setActiveChatFolder(0, { forceOnHeavyAnimation: true }));
useEffect(() => { useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => { const handleKeyDown = (e: KeyboardEvent) => {
@ -177,7 +177,7 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
const folder = Number(digit) - 1; const folder = Number(digit) - 1;
if (folder > folderTabs.length - 1) return; if (folder > folderTabs.length - 1) return;
setActiveChatFolder(folder); setActiveChatFolder(folder, { forceOnHeavyAnimation: true });
e.preventDefault(); e.preventDefault();
} }
}; };

View File

@ -337,7 +337,7 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
); );
const closeChat = () => { const closeChat = () => {
openChat({ id: undefined }, true); openChat({ id: undefined }, { forceSyncOnIOs: true });
}; };
useHistoryBack( useHistoryBack(

View File

@ -107,14 +107,14 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
setProfileState(ProfileState.Profile); setProfileState(ProfileState.Profile);
break; break;
} }
toggleChatInfo(undefined, true); toggleChatInfo(undefined, { forceSyncOnIOs: true });
break; break;
case RightColumnContent.UserInfo: case RightColumnContent.UserInfo:
if (isScrolledDown && shouldScrollUp) { if (isScrolledDown && shouldScrollUp) {
setProfileState(ProfileState.Profile); setProfileState(ProfileState.Profile);
break; break;
} }
openUserInfo({ id: undefined }, true); openUserInfo({ id: undefined }, { forceSyncOnIOs: true });
break; break;
case RightColumnContent.Management: { case RightColumnContent.Management: {
switch (managementScreen) { switch (managementScreen) {

View File

@ -569,4 +569,10 @@ export type ActionTypes = (
'openCallFallbackConfirm' | 'closeCallFallbackConfirm' | 'inviteToCallFallback' 'openCallFallbackConfirm' | 'closeCallFallbackConfirm' | 'inviteToCallFallback'
); );
export type GlobalActions = Record<ActionTypes, (...args: any[]) => void>; export interface DispatchOptions {
forceOnHeavyAnimation?: boolean;
// Workaround for iOS gesture history navigation
forceSyncOnIOs?: boolean;
}
export type GlobalActions = Record<ActionTypes, (payload?: any, options?: DispatchOptions) => void>;

View File

@ -8,7 +8,9 @@ import generateIdFor from '../../util/generateIdFor';
import { throttleWithRaf } from '../../util/schedulers'; import { throttleWithRaf } from '../../util/schedulers';
import arePropsShallowEqual, { getUnequalProps } from '../../util/arePropsShallowEqual'; import arePropsShallowEqual, { getUnequalProps } from '../../util/arePropsShallowEqual';
import { orderBy } from '../../util/iteratees'; import { orderBy } from '../../util/iteratees';
import { GlobalState, GlobalActions, ActionTypes } from '../../global/types'; import {
GlobalState, GlobalActions, ActionTypes, DispatchOptions,
} from '../../global/types';
import { handleError } from '../../util/handleError'; import { handleError } from '../../util/handleError';
import { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck'; import { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
@ -43,8 +45,8 @@ const containers = new Map<string, {
const runCallbacksThrottled = throttleWithRaf(runCallbacks); const runCallbacksThrottled = throttleWithRaf(runCallbacks);
function runCallbacks() { function runCallbacks(forceOnHeavyAnimation = false) {
if (isHeavyAnimating()) { if (!forceOnHeavyAnimation && isHeavyAnimating()) {
runCallbacksThrottled(); runCallbacksThrottled();
return; return;
} }
@ -52,14 +54,13 @@ function runCallbacks() {
callbacks.forEach((cb) => cb(currentGlobal)); callbacks.forEach((cb) => cb(currentGlobal));
} }
// `noThrottle = true` is used as a workaround for iOS gesture history navigation export function setGlobal(newGlobal?: GlobalState, options?: DispatchOptions) {
export function setGlobal(newGlobal?: GlobalState, noThrottle = false) {
if (typeof newGlobal === 'object' && newGlobal !== currentGlobal) { if (typeof newGlobal === 'object' && newGlobal !== currentGlobal) {
currentGlobal = newGlobal; currentGlobal = newGlobal;
if (!noThrottle) { if (options?.forceSyncOnIOs) {
runCallbacksThrottled(); runCallbacks(true);
} else { } else {
runCallbacks(); runCallbacksThrottled(options?.forceOnHeavyAnimation);
} }
} }
} }
@ -72,12 +73,12 @@ export function getDispatch() {
return actions; return actions;
} }
function onDispatch(name: string, payload?: ActionPayload, noThrottle?: boolean) { function onDispatch(name: string, payload?: ActionPayload, options?: DispatchOptions) {
if (reducers[name]) { if (reducers[name]) {
reducers[name].forEach((reducer) => { reducers[name].forEach((reducer) => {
const newGlobal = reducer(currentGlobal, actions, payload); const newGlobal = reducer(currentGlobal, actions, payload);
if (newGlobal) { if (newGlobal) {
setGlobal(newGlobal, noThrottle); setGlobal(newGlobal, options);
} }
}); });
} }
@ -151,8 +152,8 @@ export function addReducer(name: ActionTypes, reducer: Reducer) {
if (!reducers[name]) { if (!reducers[name]) {
reducers[name] = []; reducers[name] = [];
actions[name] = (payload?: ActionPayload, noThrottle = false) => { actions[name] = (payload?: ActionPayload, options?: DispatchOptions) => {
onDispatch(name, payload, noThrottle); onDispatch(name, payload, options);
}; };
} }

View File

@ -88,7 +88,7 @@ addReducer('disableHistoryAnimations', () => {
setGlobal({ setGlobal({
...getGlobal(), ...getGlobal(),
shouldSkipHistoryAnimations: true, shouldSkipHistoryAnimations: true,
}, true); }, { forceSyncOnIOs: true });
}); });
function subscribeToSystemThemeChange() { function subscribeToSystemThemeChange() {