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

View File

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

View File

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

View File

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

View File

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