Revert "Better browser history support (#1125)"

This reverts commit 3c19438f1a9f6db9a06dc3b48bd06d062befe0b8.
This commit is contained in:
Alexander Zinchuk 2021-06-14 22:12:34 +03:00
parent 70af1ed7f6
commit c3201cf632
32 changed files with 124 additions and 623 deletions

View File

@ -12,24 +12,14 @@ import InputText from '../ui/InputText';
import Loading from '../ui/Loading'; import Loading from '../ui/Loading';
import TrackingMonkey from '../common/TrackingMonkey'; import TrackingMonkey from '../common/TrackingMonkey';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import { HistoryWrapper } from '../../util/history';
type StateProps = Pick<GlobalState, 'authPhoneNumber' | 'authIsCodeViaApp' | 'authIsLoading' | 'authError'>; type StateProps = Pick<GlobalState, 'authPhoneNumber' | 'authIsCodeViaApp' | 'authIsLoading' | 'authError'>;
type DispatchProps = Pick<GlobalActions, ( type DispatchProps = Pick<GlobalActions, 'setAuthCode' | 'returnToAuthPhoneNumber' | 'clearAuthError'>;
'setAuthCode' | 'returnToAuthPhoneNumber' | 'clearAuthError' | 'setShouldSkipUiLoaderTransition'
)>;
const CODE_LENGTH = 5; const CODE_LENGTH = 5;
const AuthCode: FC<StateProps & DispatchProps> = ({ const AuthCode: FC<StateProps & DispatchProps> = ({
authPhoneNumber, authPhoneNumber, authIsCodeViaApp, authIsLoading, authError, setAuthCode, returnToAuthPhoneNumber, clearAuthError,
authIsCodeViaApp,
authIsLoading,
authError,
setAuthCode,
returnToAuthPhoneNumber,
clearAuthError,
setShouldSkipUiLoaderTransition,
}) => { }) => {
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
@ -44,15 +34,7 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
} }
}, []); }, []);
const handleBackToPhoneNumber = () => { useHistoryBack(returnToAuthPhoneNumber);
returnToAuthPhoneNumber();
HistoryWrapper.back();
};
useHistoryBack((event, noAnimation) => {
setShouldSkipUiLoaderTransition({ shouldSkipUiLoaderTransition: noAnimation });
returnToAuthPhoneNumber();
});
const onCodeChange = useCallback((e: FormEvent<HTMLInputElement>) => { const onCodeChange = useCallback((e: FormEvent<HTMLInputElement>) => {
if (authError) { if (authError) {
@ -98,7 +80,7 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
{authPhoneNumber} {authPhoneNumber}
<div <div
className="auth-number-edit" className="auth-number-edit"
onClick={handleBackToPhoneNumber} onClick={returnToAuthPhoneNumber}
role="button" role="button"
tabIndex={0} tabIndex={0}
title="Sign In with another phone number" title="Sign In with another phone number"
@ -137,10 +119,5 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal( export default memo(withGlobal(
(global): StateProps => pick(global, ['authPhoneNumber', 'authIsCodeViaApp', 'authIsLoading', 'authError']), (global): StateProps => pick(global, ['authPhoneNumber', 'authIsCodeViaApp', 'authIsLoading', 'authError']),
(setGlobal, actions): DispatchProps => pick(actions, [ (setGlobal, actions): DispatchProps => pick(actions, ['setAuthCode', 'returnToAuthPhoneNumber', 'clearAuthError']),
'setAuthCode',
'returnToAuthPhoneNumber',
'clearAuthError',
'setShouldSkipUiLoaderTransition',
]),
)(AuthCode)); )(AuthCode));

View File

@ -11,18 +11,14 @@ import Loading from '../ui/Loading';
import Button from '../ui/Button'; import Button from '../ui/Button';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import { HistoryWrapper } from '../../util/history';
type StateProps = Pick<GlobalState, 'connectionState' | 'authQrCode'>; type StateProps = Pick<GlobalState, 'connectionState' | 'authQrCode'>;
type DispatchProps = Pick<GlobalActions, 'returnToAuthPhoneNumber' | 'setShouldSkipUiLoaderTransition'>; type DispatchProps = Pick<GlobalActions, 'returnToAuthPhoneNumber'>;
const DATA_PREFIX = 'tg://login?token='; const DATA_PREFIX = 'tg://login?token=';
const AuthCode: FC<StateProps & DispatchProps> = ({ const AuthCode: FC<StateProps & DispatchProps> = ({
connectionState, connectionState, authQrCode, returnToAuthPhoneNumber,
authQrCode,
returnToAuthPhoneNumber,
setShouldSkipUiLoaderTransition,
}) => { }) => {
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const qrCodeRef = useRef<HTMLDivElement>(null); const qrCodeRef = useRef<HTMLDivElement>(null);
@ -45,15 +41,7 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
}, container); }, container);
}, [connectionState, authQrCode]); }, [connectionState, authQrCode]);
const handleBackToPhoneNumber = () => { useHistoryBack(returnToAuthPhoneNumber);
HistoryWrapper.back();
returnToAuthPhoneNumber();
};
useHistoryBack((event, noAnimation) => {
setShouldSkipUiLoaderTransition({ shouldSkipUiLoaderTransition: noAnimation });
returnToAuthPhoneNumber();
});
return ( return (
<div id="auth-qr-form" className="custom-scroll"> <div id="auth-qr-form" className="custom-scroll">
@ -67,7 +55,7 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
<li><span>Go to&nbsp;<b>Settings</b>&nbsp;&gt;&nbsp;<b>Devices</b>&nbsp;&gt;&nbsp;<b>Scan QR</b></span></li> <li><span>Go to&nbsp;<b>Settings</b>&nbsp;&gt;&nbsp;<b>Devices</b>&nbsp;&gt;&nbsp;<b>Scan QR</b></span></li>
<li><span>Point your phone at this screen to confirm login</span></li> <li><span>Point your phone at this screen to confirm login</span></li>
</ol> </ol>
<Button isText onClick={handleBackToPhoneNumber}>Log in by phone number</Button> <Button isText onClick={returnToAuthPhoneNumber}>Log in by phone number</Button>
</div> </div>
</div> </div>
); );
@ -75,5 +63,5 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal( export default memo(withGlobal(
(global): StateProps => pick(global, ['connectionState', 'authQrCode']), (global): StateProps => pick(global, ['connectionState', 'authQrCode']),
(setGlobal, actions): DispatchProps => pick(actions, ['returnToAuthPhoneNumber', 'setShouldSkipUiLoaderTransition']), (setGlobal, actions): DispatchProps => pick(actions, ['returnToAuthPhoneNumber']),
)(AuthCode)); )(AuthCode));

View File

@ -7,7 +7,6 @@ import { GlobalActions, GlobalState } from '../../global/types';
import { getChatAvatarHash } from '../../modules/helpers/chats'; // Direct import for better module splitting import { getChatAvatarHash } from '../../modules/helpers/chats'; // Direct import for better module splitting
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useOnChange from '../../hooks/useOnChange';
import { pause } from '../../util/schedulers'; import { pause } from '../../util/schedulers';
import { preloadImage } from '../../util/files'; import { preloadImage } from '../../util/files';
import preloadFonts from '../../util/fonts'; import preloadFonts from '../../util/fonts';
@ -29,18 +28,17 @@ type OwnProps = {
children: any; children: any;
}; };
type StateProps = Pick<GlobalState, 'uiReadyState' | 'shouldSkipUiLoaderTransition'> & { type StateProps = Pick<GlobalState, 'uiReadyState'> & {
hasCustomBackground?: boolean; hasCustomBackground?: boolean;
hasCustomBackgroundColor: boolean; hasCustomBackgroundColor: boolean;
isRightColumnShown?: boolean; isRightColumnShown?: boolean;
}; };
type DispatchProps = Pick<GlobalActions, 'setIsUiReady' | 'setShouldSkipUiLoaderTransition'>; type DispatchProps = Pick<GlobalActions, 'setIsUiReady'>;
const MAX_PRELOAD_DELAY = 700; const MAX_PRELOAD_DELAY = 700;
const SECOND_STATE_DELAY = 1000; const SECOND_STATE_DELAY = 1000;
const AVATARS_TO_PRELOAD = 10; const AVATARS_TO_PRELOAD = 10;
const TRANSITION_TIME = 400;
function preloadAvatars() { function preloadAvatars() {
const { listIds, byId } = getGlobal().chats; const { listIds, byId } = getGlobal().chats;
@ -84,9 +82,7 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
hasCustomBackground, hasCustomBackground,
hasCustomBackgroundColor, hasCustomBackgroundColor,
isRightColumnShown, isRightColumnShown,
shouldSkipUiLoaderTransition,
setIsUiReady, setIsUiReady,
setShouldSkipUiLoaderTransition,
}) => { }) => {
const [isReady, markReady] = useFlag(); const [isReady, markReady] = useFlag();
const { const {
@ -127,18 +123,10 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
useOnChange(() => {
if (shouldSkipUiLoaderTransition) {
setTimeout(() => {
setShouldSkipUiLoaderTransition({ shouldSkipUiLoaderTransition: false });
}, TRANSITION_TIME);
}
}, [shouldSkipUiLoaderTransition]);
return ( return (
<div id="UiLoader"> <div id="UiLoader">
{children} {children}
{shouldRenderMask && !shouldSkipUiLoaderTransition && ( {shouldRenderMask && (
<div className={buildClassName('mask', transitionClassNames)}> <div className={buildClassName('mask', transitionClassNames)}>
{page === 'main' ? ( {page === 'main' ? (
<> <>
@ -168,12 +156,11 @@ export default withGlobal<OwnProps>(
const { background, backgroundColor } = global.settings.themes[theme] || {}; const { background, backgroundColor } = global.settings.themes[theme] || {};
return { return {
shouldSkipUiLoaderTransition: global.shouldSkipUiLoaderTransition,
uiReadyState: global.uiReadyState, uiReadyState: global.uiReadyState,
hasCustomBackground: Boolean(background), hasCustomBackground: Boolean(background),
hasCustomBackgroundColor: Boolean(backgroundColor), hasCustomBackgroundColor: Boolean(backgroundColor),
isRightColumnShown: selectIsRightColumnShown(global), isRightColumnShown: selectIsRightColumnShown(global),
}; };
}, },
(setGlobal, actions): DispatchProps => pick(actions, ['setIsUiReady', 'setShouldSkipUiLoaderTransition']), (setGlobal, actions): DispatchProps => pick(actions, ['setIsUiReady']),
)(UiLoader); )(UiLoader);

View File

@ -6,19 +6,15 @@ import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types'; import { GlobalActions } from '../../global/types';
import { LeftColumnContent, SettingsScreens } from '../../types'; import { LeftColumnContent, SettingsScreens } from '../../types';
import useHistoryBack from '../../hooks/useHistoryBack';
import useFlag from '../../hooks/useFlag';
import { IS_MOBILE_SCREEN } from '../../util/environment'; import { IS_MOBILE_SCREEN } from '../../util/environment';
import captureEscKeyListener from '../../util/captureEscKeyListener'; import captureEscKeyListener from '../../util/captureEscKeyListener';
import { pick } from '../../util/iteratees'; import { pick } from '../../util/iteratees';
import Transition, { ANIMATION_DURATION } from '../ui/Transition'; import Transition from '../ui/Transition';
import LeftMain from './main/LeftMain'; import LeftMain from './main/LeftMain';
import Settings from './settings/Settings.async'; import Settings from './settings/Settings.async';
import NewChat from './newChat/NewChat.async'; import NewChat from './newChat/NewChat.async';
import ArchivedChats from './ArchivedChats.async'; import ArchivedChats from './ArchivedChats.async';
import { HistoryWrapper } from '../../util/history';
import './LeftColumn.scss'; import './LeftColumn.scss';
@ -61,32 +57,6 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
const [content, setContent] = useState<LeftColumnContent>(LeftColumnContent.ChatList); const [content, setContent] = useState<LeftColumnContent>(LeftColumnContent.ChatList);
const [settingsScreen, setSettingsScreen] = useState(SettingsScreens.Main); const [settingsScreen, setSettingsScreen] = useState(SettingsScreens.Main);
const [contactsFilter, setContactsFilter] = useState<string>(''); const [contactsFilter, setContactsFilter] = useState<string>('');
const [isMenuOpen, openMenu, closeMenu] = useFlag();
const setContentWithHistory = useCallback((contentKey: LeftColumnContent) => {
if (contentKey !== LeftColumnContent.ChatList
&& contentKey !== LeftColumnContent.NewChannelStep2
&& contentKey !== LeftColumnContent.NewGroupStep2) {
HistoryWrapper.pushState({
type: 'left',
contentKey,
isMenuOpen,
});
}
setContent(contentKey);
}, [isMenuOpen]);
const setSettingsScreenWithHistory = useCallback((screen: SettingsScreens, noPushState = false) => {
setSettingsScreen(screen);
if (!noPushState) {
HistoryWrapper.pushState({
type: 'left',
contentKey: LeftColumnContent.Settings,
screen,
isMenuOpen,
});
}
}, [isMenuOpen]);
// Used to reset child components in background. // Used to reset child components in background.
const [lastResetTime, setLastResetTime] = useState<number>(0); const [lastResetTime, setLastResetTime] = useState<number>(0);
@ -109,13 +79,12 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
break; break;
} }
const handleReset = useCallback((forceReturnToChatList?: boolean, noPushState = false) => { const handleReset = useCallback((forceReturnToChatList?: boolean) => {
if ( if (
content === LeftColumnContent.NewGroupStep2 content === LeftColumnContent.NewGroupStep2
&& !forceReturnToChatList && !forceReturnToChatList
) { ) {
if (!noPushState) HistoryWrapper.back(); setContent(LeftColumnContent.NewGroupStep1);
setContentWithHistory(LeftColumnContent.NewGroupStep1);
return; return;
} }
@ -127,9 +96,6 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
} }
if (content === LeftColumnContent.Settings) { if (content === LeftColumnContent.Settings) {
if (!noPushState) {
HistoryWrapper.back();
}
switch (settingsScreen) { switch (settingsScreen) {
case SettingsScreens.EditProfile: case SettingsScreens.EditProfile:
case SettingsScreens.Folders: case SettingsScreens.Folders:
@ -137,14 +103,14 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
case SettingsScreens.Notifications: case SettingsScreens.Notifications:
case SettingsScreens.Privacy: case SettingsScreens.Privacy:
case SettingsScreens.Language: case SettingsScreens.Language:
setSettingsScreenWithHistory(SettingsScreens.Main, noPushState); setSettingsScreen(SettingsScreens.Main);
return; return;
case SettingsScreens.GeneralChatBackground: case SettingsScreens.GeneralChatBackground:
setSettingsScreenWithHistory(SettingsScreens.General, noPushState); setSettingsScreen(SettingsScreens.General);
return; return;
case SettingsScreens.GeneralChatBackgroundColor: case SettingsScreens.GeneralChatBackgroundColor:
setSettingsScreenWithHistory(SettingsScreens.GeneralChatBackground, noPushState); setSettingsScreen(SettingsScreens.GeneralChatBackground);
return; return;
case SettingsScreens.PrivacyPhoneNumber: case SettingsScreens.PrivacyPhoneNumber:
@ -157,83 +123,79 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
case SettingsScreens.TwoFaDisabled: case SettingsScreens.TwoFaDisabled:
case SettingsScreens.TwoFaEnabled: case SettingsScreens.TwoFaEnabled:
case SettingsScreens.TwoFaCongratulations: case SettingsScreens.TwoFaCongratulations:
setSettingsScreenWithHistory(SettingsScreens.Privacy, noPushState); setSettingsScreen(SettingsScreens.Privacy);
return; return;
case SettingsScreens.PrivacyPhoneNumberAllowedContacts: case SettingsScreens.PrivacyPhoneNumberAllowedContacts:
case SettingsScreens.PrivacyPhoneNumberDeniedContacts: case SettingsScreens.PrivacyPhoneNumberDeniedContacts:
setSettingsScreenWithHistory(SettingsScreens.PrivacyPhoneNumber, noPushState); setSettingsScreen(SettingsScreens.PrivacyPhoneNumber);
return; return;
case SettingsScreens.PrivacyLastSeenAllowedContacts: case SettingsScreens.PrivacyLastSeenAllowedContacts:
case SettingsScreens.PrivacyLastSeenDeniedContacts: case SettingsScreens.PrivacyLastSeenDeniedContacts:
setSettingsScreenWithHistory(SettingsScreens.PrivacyLastSeen, noPushState); setSettingsScreen(SettingsScreens.PrivacyLastSeen);
return; return;
case SettingsScreens.PrivacyProfilePhotoAllowedContacts: case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
case SettingsScreens.PrivacyProfilePhotoDeniedContacts: case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
setSettingsScreenWithHistory(SettingsScreens.PrivacyProfilePhoto, noPushState); setSettingsScreen(SettingsScreens.PrivacyProfilePhoto);
return; return;
case SettingsScreens.PrivacyForwardingAllowedContacts: case SettingsScreens.PrivacyForwardingAllowedContacts:
case SettingsScreens.PrivacyForwardingDeniedContacts: case SettingsScreens.PrivacyForwardingDeniedContacts:
setSettingsScreenWithHistory(SettingsScreens.PrivacyForwarding, noPushState); setSettingsScreen(SettingsScreens.PrivacyForwarding);
return; return;
case SettingsScreens.PrivacyGroupChatsAllowedContacts: case SettingsScreens.PrivacyGroupChatsAllowedContacts:
case SettingsScreens.PrivacyGroupChatsDeniedContacts: case SettingsScreens.PrivacyGroupChatsDeniedContacts:
setSettingsScreenWithHistory(SettingsScreens.PrivacyGroupChats, noPushState); setSettingsScreen(SettingsScreens.PrivacyGroupChats);
return; return;
case SettingsScreens.TwoFaNewPassword: case SettingsScreens.TwoFaNewPassword:
setSettingsScreenWithHistory(SettingsScreens.TwoFaDisabled, noPushState); setSettingsScreen(SettingsScreens.TwoFaDisabled);
return; return;
case SettingsScreens.TwoFaNewPasswordConfirm: case SettingsScreens.TwoFaNewPasswordConfirm:
setSettingsScreenWithHistory(SettingsScreens.TwoFaNewPassword, noPushState); setSettingsScreen(SettingsScreens.TwoFaNewPassword);
return; return;
case SettingsScreens.TwoFaNewPasswordHint: case SettingsScreens.TwoFaNewPasswordHint:
setSettingsScreenWithHistory(SettingsScreens.TwoFaNewPasswordConfirm, noPushState); setSettingsScreen(SettingsScreens.TwoFaNewPasswordConfirm);
return; return;
case SettingsScreens.TwoFaNewPasswordEmail: case SettingsScreens.TwoFaNewPasswordEmail:
setSettingsScreenWithHistory(SettingsScreens.TwoFaNewPasswordHint, noPushState); setSettingsScreen(SettingsScreens.TwoFaNewPasswordHint);
return; return;
case SettingsScreens.TwoFaNewPasswordEmailCode: case SettingsScreens.TwoFaNewPasswordEmailCode:
setSettingsScreenWithHistory(SettingsScreens.TwoFaNewPasswordEmail, noPushState); setSettingsScreen(SettingsScreens.TwoFaNewPasswordEmail);
return; return;
case SettingsScreens.TwoFaChangePasswordCurrent: case SettingsScreens.TwoFaChangePasswordCurrent:
case SettingsScreens.TwoFaTurnOff: case SettingsScreens.TwoFaTurnOff:
case SettingsScreens.TwoFaRecoveryEmailCurrentPassword: case SettingsScreens.TwoFaRecoveryEmailCurrentPassword:
setSettingsScreenWithHistory(SettingsScreens.TwoFaEnabled, noPushState); setSettingsScreen(SettingsScreens.TwoFaEnabled);
return; return;
case SettingsScreens.TwoFaChangePasswordNew: case SettingsScreens.TwoFaChangePasswordNew:
setSettingsScreenWithHistory(SettingsScreens.TwoFaChangePasswordCurrent, noPushState); setSettingsScreen(SettingsScreens.TwoFaChangePasswordCurrent);
return; return;
case SettingsScreens.TwoFaChangePasswordConfirm: case SettingsScreens.TwoFaChangePasswordConfirm:
setSettingsScreenWithHistory(SettingsScreens.TwoFaChangePasswordNew, noPushState); setSettingsScreen(SettingsScreens.TwoFaChangePasswordNew);
return; return;
case SettingsScreens.TwoFaChangePasswordHint: case SettingsScreens.TwoFaChangePasswordHint:
setSettingsScreenWithHistory(SettingsScreens.TwoFaChangePasswordConfirm, noPushState); setSettingsScreen(SettingsScreens.TwoFaChangePasswordConfirm);
return; return;
case SettingsScreens.TwoFaRecoveryEmail: case SettingsScreens.TwoFaRecoveryEmail:
setSettingsScreenWithHistory(SettingsScreens.TwoFaRecoveryEmailCurrentPassword, noPushState); setSettingsScreen(SettingsScreens.TwoFaRecoveryEmailCurrentPassword);
return; return;
case SettingsScreens.TwoFaRecoveryEmailCode: case SettingsScreens.TwoFaRecoveryEmailCode:
setSettingsScreenWithHistory(SettingsScreens.TwoFaRecoveryEmail, noPushState); setSettingsScreen(SettingsScreens.TwoFaRecoveryEmail);
return; return;
case SettingsScreens.FoldersCreateFolder: case SettingsScreens.FoldersCreateFolder:
case SettingsScreens.FoldersEditFolder: case SettingsScreens.FoldersEditFolder:
setSettingsScreenWithHistory(SettingsScreens.Folders, noPushState); setSettingsScreen(SettingsScreens.Folders);
return; return;
default: default:
break; break;
} }
} }
if (!noPushState) {
HistoryWrapper.back();
}
if (content === LeftColumnContent.ChatList && activeChatFolder === 0) { if (content === LeftColumnContent.ChatList && activeChatFolder === 0) {
setContentWithHistory(LeftColumnContent.GlobalSearch); setContent(LeftColumnContent.GlobalSearch);
return; return;
} }
setContentWithHistory(LeftColumnContent.ChatList); setContent(LeftColumnContent.ChatList);
setContactsFilter(''); setContactsFilter('');
setGlobalSearchQuery({ query: '' }); setGlobalSearchQuery({ query: '' });
setGlobalSearchDate({ date: undefined }); setGlobalSearchDate({ date: undefined });
@ -243,35 +205,22 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
setLastResetTime(Date.now()); setLastResetTime(Date.now());
}, RESET_TRANSITION_DELAY_MS); }, RESET_TRANSITION_DELAY_MS);
}, [ }, [
content, activeChatFolder, setContentWithHistory, settingsScreen, setSettingsScreenWithHistory, content, activeChatFolder, setGlobalSearchQuery, setGlobalSearchDate, setGlobalSearchChatId, resetChatCreation,
setGlobalSearchQuery, setGlobalSearchDate, setGlobalSearchChatId, resetChatCreation, settingsScreen,
]); ]);
const [shouldSkipTransition, setShouldSkipTransition] = useState(false);
useHistoryBack((event, noAnimation, previousHistoryState) => {
if (previousHistoryState && previousHistoryState.type === 'left') {
if (noAnimation) {
setShouldSkipTransition(true);
setTimeout(() => {
setShouldSkipTransition(false);
}, ANIMATION_DURATION[IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide']);
}
handleReset(false, true);
}
});
const handleSearchQuery = useCallback((query: string) => { const handleSearchQuery = useCallback((query: string) => {
if (content === LeftColumnContent.Contacts) { if (content === LeftColumnContent.Contacts) {
setContactsFilter(query); setContactsFilter(query);
return; return;
} }
setContentWithHistory(LeftColumnContent.GlobalSearch); setContent(LeftColumnContent.GlobalSearch);
if (query !== searchQuery) { if (query !== searchQuery) {
setGlobalSearchQuery({ query }); setGlobalSearchQuery({ query });
} }
}, [content, setContentWithHistory, searchQuery, setGlobalSearchQuery]); }, [content, setGlobalSearchQuery, searchQuery]);
useEffect( useEffect(
() => (content !== LeftColumnContent.ChatList || activeChatFolder === 0 () => (content !== LeftColumnContent.ChatList || activeChatFolder === 0
@ -291,7 +240,7 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
return ( return (
<Transition <Transition
id="LeftColumn" id="LeftColumn"
name={shouldSkipTransition ? 'none' : IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'} name={IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'}
renderCount={RENDER_COUNT} renderCount={RENDER_COUNT}
activeKey={contentType} activeKey={contentType}
> >
@ -308,9 +257,8 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
return ( return (
<Settings <Settings
currentScreen={settingsScreen} currentScreen={settingsScreen}
onScreenSelect={setSettingsScreenWithHistory} onScreenSelect={setSettingsScreen}
onReset={handleReset} onReset={handleReset}
shouldSkipTransition={shouldSkipTransition}
/> />
); );
case ContentType.NewChannel: case ContentType.NewChannel:
@ -319,7 +267,7 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
key={lastResetTime} key={lastResetTime}
isChannel isChannel
content={content} content={content}
onContentChange={setContentWithHistory} onContentChange={setContent}
onReset={handleReset} onReset={handleReset}
/> />
); );
@ -328,7 +276,7 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
<NewChat <NewChat
key={lastResetTime} key={lastResetTime}
content={content} content={content}
onContentChange={setContentWithHistory} onContentChange={setContent}
onReset={handleReset} onReset={handleReset}
/> />
); );
@ -339,12 +287,9 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
searchQuery={searchQuery} searchQuery={searchQuery}
searchDate={searchDate} searchDate={searchDate}
contactsFilter={contactsFilter} contactsFilter={contactsFilter}
onContentChange={setContentWithHistory} onContentChange={setContent}
onSearchQuery={handleSearchQuery} onSearchQuery={handleSearchQuery}
onReset={handleReset} onReset={handleReset}
shouldSkipTransition={shouldSkipTransition}
onOpenMenu={openMenu}
onCloseMenu={closeMenu}
/> />
); );
} }

View File

@ -21,12 +21,9 @@ type OwnProps = {
searchQuery?: string; searchQuery?: string;
searchDate?: number; searchDate?: number;
contactsFilter: string; contactsFilter: string;
shouldSkipTransition?: boolean;
onSearchQuery: (query: string) => void; onSearchQuery: (query: string) => void;
onContentChange: (content: LeftColumnContent) => void; onContentChange: (content: LeftColumnContent) => void;
onReset: () => void; onReset: () => void;
onOpenMenu: NoneToVoidFunction;
onCloseMenu: NoneToVoidFunction;
}; };
type StateProps = {}; type StateProps = {};
@ -40,12 +37,9 @@ const LeftMain: FC<OwnProps & StateProps> = ({
searchQuery, searchQuery,
searchDate, searchDate,
contactsFilter, contactsFilter,
shouldSkipTransition,
onSearchQuery, onSearchQuery,
onContentChange, onContentChange,
onReset, onReset,
onOpenMenu,
onCloseMenu,
}) => { }) => {
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV); const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
@ -125,17 +119,10 @@ const LeftMain: FC<OwnProps & StateProps> = ({
onSelectSettings={handleSelectSettings} onSelectSettings={handleSelectSettings}
onSelectContacts={handleSelectContacts} onSelectContacts={handleSelectContacts}
onSelectArchived={handleSelectArchived} onSelectArchived={handleSelectArchived}
onOpenMenu={onOpenMenu}
onCloseMenu={onCloseMenu}
onReset={onReset} onReset={onReset}
shouldSkipTransition={shouldSkipTransition}
/> />
<ConnectionState /> <ConnectionState />
<Transition <Transition name="zoom-fade" renderCount={TRANSITION_RENDER_COUNT} activeKey={content}>
name={shouldSkipTransition ? 'none' : 'zoom-fade'}
renderCount={TRANSITION_RENDER_COUNT}
activeKey={content}
>
{(isActive) => { {(isActive) => {
switch (content) { switch (content) {
case LeftColumnContent.ChatList: case LeftColumnContent.ChatList:

View File

@ -40,14 +40,6 @@
transform: rotate(-45deg) scaleX(0.75) translate(0.375rem, 0.1875rem); transform: rotate(-45deg) scaleX(0.75) translate(0.375rem, 0.1875rem);
} }
} }
&.no-animation {
transition: none;
&::before, &::after {
transition: none;
}
}
} }
.archived-badge { .archived-badge {

View File

@ -1,5 +1,5 @@
import React, { import React, {
FC, useCallback, useMemo, memo, useState, FC, useCallback, useMemo, memo,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn'; import { withGlobal } from '../../../lib/teact/teactn';
@ -15,7 +15,6 @@ import { isChatArchived } from '../../../modules/helpers';
import { formatDateToString } from '../../../util/dateFormat'; import { formatDateToString } from '../../../util/dateFormat';
import switchTheme from '../../../util/switchTheme'; import switchTheme from '../../../util/switchTheme';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
import DropdownMenu from '../../ui/DropdownMenu'; import DropdownMenu from '../../ui/DropdownMenu';
import MenuItem from '../../ui/MenuItem'; import MenuItem from '../../ui/MenuItem';
@ -29,14 +28,11 @@ import './LeftMainHeader.scss';
type OwnProps = { type OwnProps = {
content: LeftColumnContent; content: LeftColumnContent;
contactsFilter: string; contactsFilter: string;
shouldSkipTransition?: boolean;
onSearchQuery: (query: string) => void; onSearchQuery: (query: string) => void;
onSelectSettings: () => void; onSelectSettings: () => void;
onSelectContacts: () => void; onSelectContacts: () => void;
onSelectArchived: () => void; onSelectArchived: () => void;
onReset: () => void; onReset: () => void;
onOpenMenu: NoneToVoidFunction;
onCloseMenu: NoneToVoidFunction;
}; };
type StateProps = { type StateProps = {
@ -55,7 +51,6 @@ type DispatchProps = Pick<GlobalActions, (
)>; )>;
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2]; const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
const MENU_ANIMATION_DURATION = 300;
const LEGACY_VERSION_URL = 'https://web.telegram.org/?legacy=1'; const LEGACY_VERSION_URL = 'https://web.telegram.org/?legacy=1';
const WEBK_VERSION_URL = 'https://web.telegram.org/k/'; const WEBK_VERSION_URL = 'https://web.telegram.org/k/';
@ -67,13 +62,10 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
onSelectSettings, onSelectSettings,
onSelectContacts, onSelectContacts,
onSelectArchived, onSelectArchived,
onOpenMenu,
onCloseMenu,
setGlobalSearchChatId, setGlobalSearchChatId,
onReset, onReset,
searchQuery, searchQuery,
isLoading, isLoading,
shouldSkipTransition,
currentUserId, currentUserId,
globalSearchChatId, globalSearchChatId,
searchDate, searchDate,
@ -119,15 +111,10 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
onClick={hasMenu ? onTrigger : () => onReset()} onClick={hasMenu ? onTrigger : () => onReset()}
ariaLabel={hasMenu ? lang('AccDescrOpenMenu2') : 'Return to chat list'} ariaLabel={hasMenu ? lang('AccDescrOpenMenu2') : 'Return to chat list'}
> >
<div className={buildClassName( <div className={buildClassName('animated-menu-icon', !hasMenu && 'state-back')} />
'animated-menu-icon',
!hasMenu && 'state-back',
shouldSkipTransition && 'no-animation',
)}
/>
</Button> </Button>
); );
}, [hasMenu, lang, onReset, shouldSkipTransition]); }, [hasMenu, lang, onReset]);
const handleSearchFocus = useCallback(() => { const handleSearchFocus = useCallback(() => {
if (!searchQuery) { if (!searchQuery) {
@ -172,25 +159,12 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
? lang('SearchFriends') ? lang('SearchFriends')
: lang('Search'); : lang('Search');
const [forceOpenDropdown, setForceOpenDropdown] = useState(false);
useHistoryBack((event, noAnimation, previousHistoryState) => {
if (previousHistoryState && previousHistoryState.type === 'left' && previousHistoryState.isMenuOpen
&& noAnimation) {
setForceOpenDropdown(true);
setTimeout(() => setForceOpenDropdown(false), MENU_ANIMATION_DURATION);
}
});
return ( return (
<div className="LeftMainHeader"> <div className="LeftMainHeader">
<div id="LeftMainHeader" className="left-header"> <div id="LeftMainHeader" className="left-header">
<DropdownMenu <DropdownMenu
trigger={MainButton} trigger={MainButton}
footer={`${APP_NAME} ${APP_VERSION}`} footer={`${APP_NAME} ${APP_VERSION}`}
forceOpen={forceOpenDropdown}
onOpen={onOpenMenu}
onClose={onCloseMenu}
> >
<MenuItem <MenuItem
icon="saved-messages" icon="saved-messages"

View File

@ -27,7 +27,6 @@
} }
.settings-content { .settings-content {
background: var(--color-background);
height: calc(100% - var(--header-height)); height: calc(100% - var(--header-height));
overflow-y: auto; overflow-y: auto;

View File

@ -31,7 +31,6 @@ const TRANSITION_DURATION = 200;
export type OwnProps = { export type OwnProps = {
currentScreen: SettingsScreens; currentScreen: SettingsScreens;
onScreenSelect: (screen: SettingsScreens) => void; onScreenSelect: (screen: SettingsScreens) => void;
shouldSkipTransition?: boolean;
onReset: () => void; onReset: () => void;
}; };
@ -39,7 +38,6 @@ const Settings: FC<OwnProps> = ({
currentScreen, currentScreen,
onScreenSelect, onScreenSelect,
onReset, onReset,
shouldSkipTransition,
}) => { }) => {
const [foldersState, foldersDispatch] = useFoldersReducer(); const [foldersState, foldersDispatch] = useFoldersReducer();
const [twoFaState, twoFaDispatch] = useTwoFaReducer(); const [twoFaState, twoFaDispatch] = useTwoFaReducer();
@ -215,7 +213,7 @@ const Settings: FC<OwnProps> = ({
return ( return (
<Transition <Transition
id="Settings" id="Settings"
name={shouldSkipTransition ? 'none' : IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'} name={IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'}
activeKey={currentScreen} activeKey={currentScreen}
renderCount={TRANSITION_RENDER_COUNT} renderCount={TRANSITION_RENDER_COUNT}
> >

View File

@ -87,14 +87,6 @@
overflow: hidden; overflow: hidden;
} }
} }
#Main.history-animation-disabled & {
transition: none;
&:after {
transition: none;
}
}
} }
@media (max-width: 600px) { @media (max-width: 600px) {
@ -112,18 +104,6 @@
@media (max-width: 600px) { @media (max-width: 600px) {
height: calc(var(--vh, 1vh) * 100 + 1px); height: calc(var(--vh, 1vh) * 100 + 1px);
} }
#Main.history-animation-disabled & {
transition: none;
.overlay-backdrop {
transition: none;
}
}
}
#Main.history-animation-disabled .overlay-backdrop {
transition: none;
} }
#MiddleColumn { #MiddleColumn {
@ -175,14 +155,6 @@
transform: translate3d(-20vw, 0, 0); transform: translate3d(-20vw, 0, 0);
} }
} }
#Main.history-animation-disabled & {
transition: none;
&:after {
transition: none;
}
}
} }
.SymbolMenu { .SymbolMenu {

View File

@ -1,6 +1,4 @@
import React, { import React, { FC, useEffect, memo } from '../../lib/teact/teact';
FC, useEffect, memo, useState,
} from '../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../lib/teact/teactn'; import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types'; import { GlobalActions } from '../../global/types';
@ -8,7 +6,7 @@ import { ApiMessage } from '../../api/types';
import '../../modules/actions/all'; import '../../modules/actions/all';
import { import {
ANIMATION_END_DELAY, DEBUG, INACTIVE_MARKER, PAGE_TITLE, SLIDE_TRANSITION_DURATION, ANIMATION_END_DELAY, DEBUG, INACTIVE_MARKER, PAGE_TITLE,
} from '../../config'; } from '../../config';
import { pick } from '../../util/iteratees'; import { pick } from '../../util/iteratees';
import { import {
@ -22,7 +20,6 @@ import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useBackgroundMode from '../../hooks/useBackgroundMode'; import useBackgroundMode from '../../hooks/useBackgroundMode';
import useHistoryBack from '../../hooks/useHistoryBack';
import LeftColumn from '../left/LeftColumn'; import LeftColumn from '../left/LeftColumn';
import MiddleColumn from '../middle/MiddleColumn'; import MiddleColumn from '../middle/MiddleColumn';
@ -49,7 +46,7 @@ type StateProps = {
safeLinkModalUrl?: string; safeLinkModalUrl?: string;
}; };
type DispatchProps = Pick<GlobalActions, 'loadAnimatedEmojis' | 'openChat'>; type DispatchProps = Pick<GlobalActions, 'loadAnimatedEmojis'>;
const ANIMATION_DURATION = 350; const ANIMATION_DURATION = 350;
const NOTIFICATION_INTERVAL = 1000; const NOTIFICATION_INTERVAL = 1000;
@ -62,7 +59,6 @@ let DEBUG_isLogged = false;
const Main: FC<StateProps & DispatchProps> = ({ const Main: FC<StateProps & DispatchProps> = ({
lastSyncTime, lastSyncTime,
loadAnimatedEmojis, loadAnimatedEmojis,
openChat,
isLeftColumnShown, isLeftColumnShown,
isRightColumnShown, isRightColumnShown,
isMediaViewerOpen, isMediaViewerOpen,
@ -86,21 +82,17 @@ const Main: FC<StateProps & DispatchProps> = ({
} }
}, [lastSyncTime, loadAnimatedEmojis]); }, [lastSyncTime, loadAnimatedEmojis]);
const [isHistoryAnimationDisabled, setIsHistoryAnimationDisabled] = useState(false);
const { const {
transitionClassNames: middleColumnTransitionClassNames, transitionClassNames: middleColumnTransitionClassNames,
} = useShowTransition(!isLeftColumnShown, undefined, true, undefined, isHistoryAnimationDisabled); } = useShowTransition(!isLeftColumnShown, undefined, true);
const { const {
transitionClassNames: rightColumnTransitionClassNames, transitionClassNames: rightColumnTransitionClassNames,
} = useShowTransition(isRightColumnShown, undefined, true, undefined, isHistoryAnimationDisabled); } = useShowTransition(isRightColumnShown, undefined, true);
const className = buildClassName( const className = buildClassName(
middleColumnTransitionClassNames.replace(/([\w-]+)/g, 'middle-column-$1'), middleColumnTransitionClassNames.replace(/([\w-]+)/g, 'middle-column-$1'),
rightColumnTransitionClassNames.replace(/([\w-]+)/g, 'right-column-$1'), rightColumnTransitionClassNames.replace(/([\w-]+)/g, 'right-column-$1'),
isHistoryAnimationDisabled && 'history-animation-disabled',
); );
useEffect(() => { useEffect(() => {
@ -168,34 +160,6 @@ const Main: FC<StateProps & DispatchProps> = ({
e.stopPropagation(); e.stopPropagation();
} }
useHistoryBack((event, noAnimation) => {
const { state } = event;
if (state.type !== 'right') {
if (state.type === 'chat') {
const { chatId: id, threadId, messageListType: type } = state;
openChat({
id, threadId, type, noPushState: true,
}, true);
} else {
openChat({
id: undefined,
noPushState: true,
}, true);
}
}
// Must disable pane closing animation for back/forward gestures on iOS
if (noAnimation) {
setIsHistoryAnimationDisabled(true);
setTimeout(() => {
setIsHistoryAnimationDisabled(false);
}, SLIDE_TRANSITION_DURATION);
}
});
return ( return (
<div id="Main" className={className} onDrop={stopEvent} onDragOver={stopEvent}> <div id="Main" className={className} onDrop={stopEvent} onDragOver={stopEvent}>
<LeftColumn /> <LeftColumn />
@ -244,5 +208,5 @@ export default memo(withGlobal(
safeLinkModalUrl: global.safeLinkModalUrl, safeLinkModalUrl: global.safeLinkModalUrl,
}; };
}, },
(setGlobal, actions): DispatchProps => pick(actions, ['loadAnimatedEmojis', 'openChat']), (setGlobal, actions): DispatchProps => pick(actions, ['loadAnimatedEmojis']),
)(Main)); )(Main));

View File

@ -153,7 +153,7 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
size="smaller" size="smaller"
round round
color="translucent" color="translucent"
onClick={() => closeLocalTextSearch({ noPushState: true })} onClick={closeLocalTextSearch}
> >
<i className="icon-arrow-left" /> <i className="icon-arrow-left" />
</Button> </Button>

View File

@ -17,7 +17,6 @@ import {
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps'; import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/useWindowSize';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev'; import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useHistoryBack from '../../hooks/useHistoryBack';
import RightHeader from './RightHeader'; import RightHeader from './RightHeader';
import Profile from './Profile'; import Profile from './Profile';
@ -27,7 +26,6 @@ import Management from './management/Management.async';
import StickerSearch from './StickerSearch.async'; import StickerSearch from './StickerSearch.async';
import GifSearch from './GifSearch.async'; import GifSearch from './GifSearch.async';
import PollResults from './PollResults.async'; import PollResults from './PollResults.async';
import { HistoryWrapper } from '../../util/history';
import './RightColumn.scss'; import './RightColumn.scss';
@ -90,26 +88,26 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
const renderingContentKey = useCurrentOrPrev(contentKey, true, !isChatSelected) ?? -1; const renderingContentKey = useCurrentOrPrev(contentKey, true, !isChatSelected) ?? -1;
const close = useCallback((noPushState = false) => { const close = useCallback(() => {
switch (contentKey) { switch (contentKey) {
case RightColumnContent.ChatInfo: case RightColumnContent.ChatInfo:
if (isScrolledDown) { if (isScrolledDown) {
setProfileState(ProfileState.Profile); setProfileState(ProfileState.Profile);
if (!noPushState) break; break;
} }
toggleChatInfo({ noPushState }, true); toggleChatInfo();
break; break;
case RightColumnContent.UserInfo: case RightColumnContent.UserInfo:
if (isScrolledDown) { if (isScrolledDown) {
setProfileState(ProfileState.Profile); setProfileState(ProfileState.Profile);
if (!noPushState) break; break;
} }
openUserInfo({ id: undefined }); openUserInfo({ id: undefined });
break; break;
case RightColumnContent.Management: { case RightColumnContent.Management: {
switch (managementScreen) { switch (managementScreen) {
case ManagementScreens.Initial: case ManagementScreens.Initial:
toggleManagement({ noPushState }, true); toggleManagement();
break; break;
case ManagementScreens.ChatPrivacyType: case ManagementScreens.ChatPrivacyType:
case ManagementScreens.Discussion: case ManagementScreens.Discussion:
@ -118,28 +116,17 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
case ManagementScreens.ChatAdministrators: case ManagementScreens.ChatAdministrators:
case ManagementScreens.ChannelSubscribers: case ManagementScreens.ChannelSubscribers:
case ManagementScreens.GroupMembers: case ManagementScreens.GroupMembers:
if (!noPushState) {
HistoryWrapper.back();
}
setManagementScreen(ManagementScreens.Initial); setManagementScreen(ManagementScreens.Initial);
break; break;
case ManagementScreens.GroupUserPermissionsCreate: case ManagementScreens.GroupUserPermissionsCreate:
case ManagementScreens.GroupRemovedUsers: case ManagementScreens.GroupRemovedUsers:
case ManagementScreens.GroupUserPermissions: case ManagementScreens.GroupUserPermissions:
if (!noPushState) {
HistoryWrapper.back();
}
setManagementScreen(ManagementScreens.GroupPermissions); setManagementScreen(ManagementScreens.GroupPermissions);
setSelectedChatMemberId(undefined); setSelectedChatMemberId(undefined);
setIsPromotedByCurrentUser(undefined); setIsPromotedByCurrentUser(undefined);
break; break;
case ManagementScreens.ChatAdminRights: case ManagementScreens.ChatAdminRights:
case ManagementScreens.GroupRecentActions: case ManagementScreens.GroupRecentActions:
if (!noPushState) {
HistoryWrapper.back();
}
setManagementScreen(ManagementScreens.ChatAdministrators); setManagementScreen(ManagementScreens.ChatAdministrators);
break; break;
} }
@ -148,20 +135,18 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
} }
case RightColumnContent.Search: { case RightColumnContent.Search: {
blurSearchInput(); blurSearchInput();
closeLocalTextSearch({ noPushState }); closeLocalTextSearch();
break; break;
} }
case RightColumnContent.StickerSearch: case RightColumnContent.StickerSearch:
blurSearchInput();
setStickerSearchQuery({ query: undefined, noPushState });
break;
case RightColumnContent.GifSearch: { case RightColumnContent.GifSearch: {
blurSearchInput(); blurSearchInput();
setGifSearchQuery({ query: undefined, noPushState }); setStickerSearchQuery({ query: undefined });
setGifSearchQuery({ query: undefined });
break; break;
} }
case RightColumnContent.PollResults: case RightColumnContent.PollResults:
closePollResults({ noPushState }); closePollResults();
break; break;
} }
}, [ }, [
@ -169,32 +154,11 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
managementScreen, toggleManagement, closeLocalTextSearch, setStickerSearchQuery, setGifSearchQuery, managementScreen, toggleManagement, closeLocalTextSearch, setStickerSearchQuery, setGifSearchQuery,
]); ]);
const handleClose = useCallback(() => {
close(false);
}, [close]);
useHistoryBack((event, noAnimation, previousHistoryState) => {
if (previousHistoryState && previousHistoryState.type === 'right') {
if (noAnimation) {
setShouldSkipTransition(true);
setTimeout(() => setShouldSkipTransition(false), COLUMN_CLOSE_DELAY_MS);
}
close(true);
}
});
const handleSelectChatMember = useCallback((memberId, isPromoted) => { const handleSelectChatMember = useCallback((memberId, isPromoted) => {
setSelectedChatMemberId(memberId); setSelectedChatMemberId(memberId);
setIsPromotedByCurrentUser(isPromoted); setIsPromotedByCurrentUser(isPromoted);
}, []); }, []);
const handleManagementScreenSelect = useCallback((screen: ManagementScreens) => {
if (screen !== managementScreen) {
HistoryWrapper.pushState({ type: 'right', contentKey });
setManagementScreen(screen);
}
}, [contentKey, managementScreen]);
useEffect(() => (isOpen ? captureEscKeyListener(close) : undefined), [isOpen, close]); useEffect(() => (isOpen ? captureEscKeyListener(close) : undefined), [isOpen, close]);
useEffect(() => { useEffect(() => {
@ -250,11 +214,10 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
currentScreen={managementScreen} currentScreen={managementScreen}
isPromotedByCurrentUser={isPromotedByCurrentUser} isPromotedByCurrentUser={isPromotedByCurrentUser}
selectedChatMemberId={selectedChatMemberId} selectedChatMemberId={selectedChatMemberId}
onScreenSelect={handleManagementScreenSelect} onScreenSelect={setManagementScreen}
onChatMemberSelect={handleSelectChatMember} onChatMemberSelect={handleSelectChatMember}
/> />
); );
case RightColumnContent.StickerSearch: case RightColumnContent.StickerSearch:
return <StickerSearch />; return <StickerSearch />;
case RightColumnContent.GifSearch: case RightColumnContent.GifSearch:
@ -284,8 +247,7 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
isPollResults={isPollResults} isPollResults={isPollResults}
profileState={profileState} profileState={profileState}
managementScreen={managementScreen} managementScreen={managementScreen}
onClose={handleClose} onClose={close}
shouldSkipAnimation={shouldSkipTransition}
/> />
<Transition <Transition
name={shouldSkipTransition ? 'none' : 'zoom-fade'} name={shouldSkipTransition ? 'none' : 'zoom-fade'}

View File

@ -37,7 +37,6 @@ type OwnProps = {
isStickerSearch?: boolean; isStickerSearch?: boolean;
isGifSearch?: boolean; isGifSearch?: boolean;
isPollResults?: boolean; isPollResults?: boolean;
shouldSkipAnimation?: boolean;
profileState?: ProfileState; profileState?: ProfileState;
managementScreen?: ManagementScreens; managementScreen?: ManagementScreens;
onClose: () => void; onClose: () => void;
@ -104,7 +103,6 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
searchTextMessagesLocal, searchTextMessagesLocal,
toggleManagement, toggleManagement,
searchMessagesByDate, searchMessagesByDate,
shouldSkipAnimation,
}) => { }) => {
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const backButtonRef = useRef<HTMLDivElement>(null); const backButtonRef = useRef<HTMLDivElement>(null);
@ -125,11 +123,11 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
}, [closeCalendar, searchMessagesByDate]); }, [closeCalendar, searchMessagesByDate]);
const handleStickerSearchQueryChange = useCallback((query: string) => { const handleStickerSearchQueryChange = useCallback((query: string) => {
setStickerSearchQuery({ query, noPushState: true }); setStickerSearchQuery({ query });
}, [setStickerSearchQuery]); }, [setStickerSearchQuery]);
const handleGifSearchQueryChange = useCallback((query: string) => { const handleGifSearchQueryChange = useCallback((query: string) => {
setGifSearchQuery({ query, noPushState: true }); setGifSearchQuery({ query });
}, [setGifSearchQuery]); }, [setGifSearchQuery]);
const [shouldSkipTransition, setShouldSkipTransition] = useState(!isColumnOpen); const [shouldSkipTransition, setShouldSkipTransition] = useState(!isColumnOpen);
@ -288,7 +286,7 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
const buttonClassName = buildClassName( const buttonClassName = buildClassName(
'animated-close-icon', 'animated-close-icon',
(shouldSkipTransition || shouldSkipAnimation) && 'no-transition', shouldSkipTransition && 'no-transition',
); );
// Add class in the next AF to synchronize with animation with Transition components // Add class in the next AF to synchronize with animation with Transition components
@ -309,7 +307,7 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
<div ref={backButtonRef} className={buttonClassName} /> <div ref={backButtonRef} className={buttonClassName} />
</Button> </Button>
<Transition <Transition
name={(shouldSkipTransition || shouldSkipAnimation) ? 'none' : 'slide-fade'} name={shouldSkipTransition ? 'none' : 'slide-fade'}
activeKey={renderingContentKey} activeKey={renderingContentKey}
> >
{renderHeaderContent} {renderHeaderContent}

View File

@ -10,9 +10,6 @@ type OwnProps = {
positionX?: 'left' | 'right'; positionX?: 'left' | 'right';
positionY?: 'top' | 'bottom'; positionY?: 'top' | 'bottom';
footer?: string; footer?: string;
forceOpen?: boolean;
onOpen?: NoneToVoidFunction;
onClose?: NoneToVoidFunction;
children: any; children: any;
}; };
@ -23,9 +20,6 @@ const DropdownMenu: FC<OwnProps> = ({
positionX = 'left', positionX = 'left',
positionY = 'top', positionY = 'top',
footer, footer,
forceOpen,
onOpen,
onClose,
}) => { }) => {
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);
@ -35,9 +29,6 @@ const DropdownMenu: FC<OwnProps> = ({
const toggleIsOpen = () => { const toggleIsOpen = () => {
setIsOpen(!isOpen); setIsOpen(!isOpen);
if (isOpen) {
if (onClose) onClose();
} else if (onOpen) onOpen();
}; };
const handleKeyDown = (e: React.KeyboardEvent<any>) => { const handleKeyDown = (e: React.KeyboardEvent<any>) => {
@ -57,7 +48,6 @@ const DropdownMenu: FC<OwnProps> = ({
const handleClose = () => { const handleClose = () => {
setIsOpen(false); setIsOpen(false);
if (onClose) onClose();
}; };
return ( return (
@ -71,14 +61,13 @@ const DropdownMenu: FC<OwnProps> = ({
<Menu <Menu
ref={menuRef} ref={menuRef}
containerRef={dropdownRef} containerRef={dropdownRef}
isOpen={isOpen || !!forceOpen} isOpen={isOpen}
className={className || ''} className={className || ''}
positionX={positionX} positionX={positionX}
positionY={positionY} positionY={positionY}
footer={footer} footer={footer}
autoClose autoClose
onClose={handleClose} onClose={handleClose}
shouldSkipTransition={forceOpen}
> >
{children} {children}
</Menu> </Menu>

View File

@ -20,7 +20,6 @@ type OwnProps = {
positionX?: 'left' | 'right'; positionX?: 'left' | 'right';
positionY?: 'top' | 'bottom'; positionY?: 'top' | 'bottom';
autoClose?: boolean; autoClose?: boolean;
shouldSkipTransition?: boolean;
footer?: string; footer?: string;
noCloseOnBackdrop?: boolean; noCloseOnBackdrop?: boolean;
onKeyDown?: (e: React.KeyboardEvent<any>) => void; onKeyDown?: (e: React.KeyboardEvent<any>) => void;
@ -49,7 +48,6 @@ const Menu: FC<OwnProps> = ({
onClose, onClose,
onMouseEnter, onMouseEnter,
onMouseLeave, onMouseLeave,
shouldSkipTransition,
}) => { }) => {
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
let menuRef = useRef<HTMLDivElement>(null); let menuRef = useRef<HTMLDivElement>(null);
@ -58,20 +56,9 @@ const Menu: FC<OwnProps> = ({
} }
const backdropContainerRef = containerRef || menuRef; const backdropContainerRef = containerRef || menuRef;
const { const { transitionClassNames } = useShowTransition(isOpen, onCloseAnimationEnd);
transitionClassNames,
} = useShowTransition(
isOpen,
onCloseAnimationEnd,
shouldSkipTransition,
undefined,
shouldSkipTransition,
);
useEffect( useEffect(() => (isOpen && onClose ? captureEscKeyListener(onClose) : undefined), [isOpen, onClose]);
() => (isOpen && onClose ? captureEscKeyListener(onClose) : undefined),
[isOpen, onClose],
);
useEffectWithPrevDeps(([prevIsOpen]) => { useEffectWithPrevDeps(([prevIsOpen]) => {
if (prevIsOpen !== undefined) { if (prevIsOpen !== undefined) {

View File

@ -1,8 +1,5 @@
import React, { import React, { FC, useEffect, useRef } from '../../lib/teact/teact';
FC, useEffect, useRef, useState,
} from '../../lib/teact/teact';
import { HistoryWrapper } from '../../util/history';
import captureKeyboardListeners from '../../util/captureKeyboardListeners'; import captureKeyboardListeners from '../../util/captureKeyboardListeners';
import trapFocus from '../../util/trapFocus'; import trapFocus from '../../util/trapFocus';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
@ -10,8 +7,6 @@ import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useHistoryBack from '../../hooks/useHistoryBack';
import useOnChange from '../../hooks/useOnChange';
import Button from './Button'; import Button from './Button';
import Portal from './Portal'; import Portal from './Portal';
@ -46,13 +41,7 @@ const Modal: FC<OwnProps> = (props) => {
onCloseAnimationEnd, onCloseAnimationEnd,
onEnter, onEnter,
} = props; } = props;
const [isClosedWithHistory, setIsClosedWithHistory] = useState(false); const { shouldRender, transitionClassNames } = useShowTransition(isOpen, onCloseAnimationEnd);
const [noAnimations, setNoAnimations] = useState(false);
const [isFirstRender, setIsFirstRender] = useState(true);
const {
shouldRender,
transitionClassNames,
} = useShowTransition(isOpen, onCloseAnimationEnd, noAnimations, undefined, noAnimations);
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const modalRef = useRef<HTMLDivElement>(null); const modalRef = useRef<HTMLDivElement>(null);
@ -61,33 +50,6 @@ const Modal: FC<OwnProps> = (props) => {
: undefined), [isOpen, onClose, onEnter]); : undefined), [isOpen, onClose, onEnter]);
useEffect(() => (isOpen && modalRef.current ? trapFocus(modalRef.current) : undefined), [isOpen]); useEffect(() => (isOpen && modalRef.current ? trapFocus(modalRef.current) : undefined), [isOpen]);
useHistoryBack((event, noAnimation, previousHistoryState) => {
if (previousHistoryState && previousHistoryState.type === 'modal') {
setIsClosedWithHistory(true);
if (noAnimation) {
setNoAnimations(true);
setTimeout(() => setNoAnimations(false), ANIMATION_DURATION);
}
onClose();
}
});
useOnChange(() => {
if (isFirstRender) {
setIsFirstRender(false);
return;
}
if (isOpen) {
HistoryWrapper.pushState({
type: 'modal',
});
} else if (!isClosedWithHistory) {
HistoryWrapper.back();
} else {
setIsClosedWithHistory(false);
}
}, [isOpen]);
useEffectWithPrevDeps(([prevIsOpen]) => { useEffectWithPrevDeps(([prevIsOpen]) => {
document.body.classList.toggle('has-open-dialog', isOpen); document.body.classList.toggle('has-open-dialog', isOpen);

View File

@ -19,10 +19,6 @@
} }
} }
&.skip-slide-transition {
transition: none !important;
}
/* /*
* scroll-slide * scroll-slide
*/ */

View File

@ -36,7 +36,7 @@ type StateProps = {
animationLevel: number; animationLevel: number;
}; };
export const ANIMATION_DURATION = { const ANIMATION_DURATION = {
slide: 450, slide: 450,
'slide-reversed': 450, 'slide-reversed': 450,
'mv-slide': 400, 'mv-slide': 400,

View File

@ -64,7 +64,6 @@ export type GlobalState = {
isLeftColumnShown: boolean; isLeftColumnShown: boolean;
isPollModalOpen?: boolean; isPollModalOpen?: boolean;
uiReadyState: 0 | 1 | 2; uiReadyState: 0 | 1 | 2;
shouldSkipUiLoaderTransition?: boolean;
connectionState?: ApiUpdateConnectionStateType; connectionState?: ApiUpdateConnectionStateType;
currentUserId?: number; currentUserId?: number;
lastSyncTime?: number; lastSyncTime?: number;
@ -398,7 +397,7 @@ export type ActionTypes = (
'showNotification' | 'dismissNotification' | 'showError' | 'dismissError' | 'showNotification' | 'dismissNotification' | 'showError' | 'dismissError' |
// ui // ui
'toggleChatInfo' | 'setIsUiReady' | 'addRecentEmoji' | 'addRecentSticker' | 'toggleLeftColumn' | 'toggleChatInfo' | 'setIsUiReady' | 'addRecentEmoji' | 'addRecentSticker' | 'toggleLeftColumn' |
'toggleSafeLinkModal' | 'setShouldSkipUiLoaderTransition' | 'toggleSafeLinkModal' |
// auth // auth
'setAuthPhoneNumber' | 'setAuthCode' | 'setAuthPassword' | 'signUp' | 'returnToAuthPhoneNumber' | 'signOut' | 'setAuthPhoneNumber' | 'setAuthCode' | 'setAuthPassword' | 'signUp' | 'returnToAuthPhoneNumber' | 'signOut' |
'setAuthRememberMe' | 'clearAuthError' | 'uploadProfilePhoto' | 'gotToAuthQrCode' | 'clearCache' | 'setAuthRememberMe' | 'clearAuthError' | 'uploadProfilePhoto' | 'gotToAuthQrCode' | 'clearCache' |

View File

@ -1,60 +1,15 @@
// This is unsafe and can be not chained as `popstate` event is asynchronous // This is unsafe and can be not chained as `popstate` event is asynchronous
import { useEffect } from '../lib/teact/teact'; export default function useHistoryBack(handler: NoneToVoidFunction) {
import { IS_IOS } from '../util/environment'; function handlePopState() {
import { HistoryWrapper } from '../util/history'; handler();
type HistoryBackFunction = ((event: PopStateEvent, noAnimation: boolean, previousHistoryState: any) => void);
// Carefully selected by swiping and observing visual changes
// TODO: may be different on other devices such as iPad, maybe take dpi into account?
const SAFARI_EDGE_BACK_GESTURE_LIMIT = 60;
const SAFARI_EDGE_BACK_GESTURE_DURATION = 200;
let isEdge = false;
const onTouchStart = (event: TouchEvent) => {
const x = event.touches[0].pageX;
if (x <= SAFARI_EDGE_BACK_GESTURE_LIMIT || x >= window.innerWidth - SAFARI_EDGE_BACK_GESTURE_LIMIT) {
isEdge = true;
} }
};
const onTouchEnd = () => { window.addEventListener('popstate', handlePopState);
if (isEdge) { window.history.pushState({}, '');
setTimeout(() => {
isEdge = false;
}, SAFARI_EDGE_BACK_GESTURE_DURATION);
}
};
if (IS_IOS) { return () => {
// eslint-disable-next-line no-console window.removeEventListener('popstate', handlePopState);
console.log('Adding event listeners for useHistoryBack'); window.history.back();
window.addEventListener('touchstart', onTouchStart);
window.addEventListener('touchend', onTouchEnd);
}
export default function useHistoryBack(handler: NoneToVoidFunction | HistoryBackFunction) {
const onPopState = (event: PopStateEvent) => {
// Check if the event was caused by History API call or the user
if (!HistoryWrapper.isHistoryChangedByUser) {
// HACK: Handle multiple event listeners.
// onTickChange doesn't work on Safari for some reason
setTimeout(() => {
HistoryWrapper.isHistoryChangedByUser = true;
}, 0);
return;
}
handler(event, isEdge, HistoryWrapper.states[HistoryWrapper.states.length - 1]);
}; };
useEffect(() => {
window.addEventListener('popstate', onPopState);
return () => {
window.removeEventListener('popstate', onPopState);
};
});
} }

View File

@ -44,7 +44,7 @@ export default (
const transitionClassNames = buildClassName( const transitionClassNames = buildClassName(
className && 'opacity-transition', className && 'opacity-transition',
className, className,
((hasOpenClassName && !noCloseTransition) || (noCloseTransition && isOpen)) && 'open', hasOpenClassName && 'open',
shouldRender && 'shown', shouldRender && 'shown',
isClosing && 'closing', isClosing && 'closing',
); );

View File

@ -46,15 +46,10 @@ function runCallbacks() {
const runCallbacksThrottled = throttleWithRaf(runCallbacks); const runCallbacksThrottled = throttleWithRaf(runCallbacks);
// noThrottle = true is used as a workaround for iOS gesture history navigation export function setGlobal(newGlobal?: GlobalState) {
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) { runCallbacksThrottled();
runCallbacksThrottled();
} else {
runCallbacks();
}
} }
} }
@ -66,12 +61,12 @@ export function getDispatch() {
return actions; return actions;
} }
function onDispatch(name: string, payload?: ActionPayload, noThrottle?: boolean) { function onDispatch(name: string, payload?: ActionPayload) {
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);
} }
}); });
} }
@ -144,8 +139,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) => {
onDispatch(name, payload, noThrottle); onDispatch(name, payload);
}; };
} }

View File

@ -15,7 +15,6 @@ import {
import { initApi, callApi } from '../../../api/gramjs'; import { initApi, callApi } from '../../../api/gramjs';
import { unsubscribe } from '../../../util/notifications'; import { unsubscribe } from '../../../util/notifications';
import * as cacheApi from '../../../util/cacheApi'; import * as cacheApi from '../../../util/cacheApi';
import { HistoryWrapper } from '../../../util/history';
import { updateAppBadge } from '../../../util/appBadge'; import { updateAppBadge } from '../../../util/appBadge';
import { import {
storeSession, storeSession,
@ -105,11 +104,6 @@ addReducer('returnToAuthPhoneNumber', (global) => {
addReducer('gotToAuthQrCode', (global) => { addReducer('gotToAuthQrCode', (global) => {
void callApi('restartAuthWithQr'); void callApi('restartAuthWithQr');
HistoryWrapper.pushState({
type: 'login',
contentKey: 'authQr',
});
return { return {
...global, ...global,
authIsLoadingQrCode: true, authIsLoadingQrCode: true,

View File

@ -1,10 +1,21 @@
import { addReducer, setGlobal } from '../../../lib/teact/teactn'; import { addReducer, getDispatch, setGlobal } from '../../../lib/teact/teactn';
import { import {
exitMessageSelectMode, exitMessageSelectMode,
updateCurrentMessageList, updateCurrentMessageList,
} from '../../reducers'; } from '../../reducers';
import { selectCurrentMessageList, selectRightColumnContentKey } from '../../selectors'; import { selectCurrentMessageList } from '../../selectors';
import { HistoryWrapper } from '../../../util/history';
window.addEventListener('popstate', (e) => {
if (!e.state) {
return;
}
const { chatId: id, threadId, messageListType: type } = e.state;
getDispatch().openChat({
id, threadId, type, noPushState: true,
});
});
addReducer('openChat', (global, actions, payload) => { addReducer('openChat', (global, actions, payload) => {
const { const {
@ -35,16 +46,7 @@ addReducer('openChat', (global, actions, payload) => {
setGlobal(global); setGlobal(global);
if (!noPushState) { if (!noPushState) {
if (id !== undefined) { window.history.pushState({ chatId: id, threadId, messageListType: type }, '');
HistoryWrapper.pushState({
type: 'chat',
chatId: id,
threadId,
messageListType: type,
});
} else {
HistoryWrapper.back();
}
} }
} }
@ -57,11 +59,6 @@ addReducer('openChatWithInfo', (global, actions, payload) => {
isChatInfoShown: true, isChatInfoShown: true,
}); });
HistoryWrapper.pushState({
type: 'right',
contentKey: selectRightColumnContentKey(global),
});
actions.openChat(payload); actions.openChat(payload);
}); });

View File

@ -5,7 +5,6 @@ import {
} from '../../../util/environment'; } from '../../../util/environment';
import { setLanguage } from '../../../util/langProvider'; import { setLanguage } from '../../../util/langProvider';
import switchTheme from '../../../util/switchTheme'; import switchTheme from '../../../util/switchTheme';
import { HistoryWrapper } from '../../../util/history';
addReducer('init', (global) => { addReducer('init', (global) => {
const { const {
@ -46,11 +45,6 @@ addReducer('setIsUiReady', (global, actions, payload) => {
addReducer('setAuthPhoneNumber', (global, actions, payload) => { addReducer('setAuthPhoneNumber', (global, actions, payload) => {
const { phoneNumber } = payload!; const { phoneNumber } = payload!;
HistoryWrapper.pushState({
type: 'login',
contentKey: 'authCode',
});
return { return {
...global, ...global,
authPhoneNumber: phoneNumber, authPhoneNumber: phoneNumber,
@ -70,12 +64,3 @@ addReducer('clearAuthError', (global) => {
authError: undefined, authError: undefined,
}; };
}); });
addReducer('setShouldSkipUiLoaderTransition', (global, actions, payload) => {
const { shouldSkipUiLoaderTransition } = payload;
return {
...global,
shouldSkipUiLoaderTransition,
};
});

View File

@ -8,8 +8,6 @@ import {
import { MEMO_EMPTY_ARRAY } from '../../../util/memo'; import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { selectCurrentMessageList } from '../../selectors'; import { selectCurrentMessageList } from '../../selectors';
import { buildChatThreadKey } from '../../helpers'; import { buildChatThreadKey } from '../../helpers';
import { HistoryWrapper } from '../../../util/history';
import { RightColumnContent } from '../../../types';
addReducer('openLocalTextSearch', (global) => { addReducer('openLocalTextSearch', (global) => {
const { chatId, threadId } = selectCurrentMessageList(global) || {}; const { chatId, threadId } = selectCurrentMessageList(global) || {};
@ -17,25 +15,15 @@ addReducer('openLocalTextSearch', (global) => {
return undefined; return undefined;
} }
HistoryWrapper.pushState({
type: 'right',
contentKey: RightColumnContent.Search,
});
return updateLocalTextSearch(global, chatId, threadId, true); return updateLocalTextSearch(global, chatId, threadId, true);
}); });
addReducer('closeLocalTextSearch', (global, actions, payload) => { addReducer('closeLocalTextSearch', (global) => {
const { noPushState } = payload;
const { chatId, threadId } = selectCurrentMessageList(global) || {}; const { chatId, threadId } = selectCurrentMessageList(global) || {};
if (!chatId || !threadId) { if (!chatId || !threadId) {
return undefined; return undefined;
} }
if (!noPushState) {
HistoryWrapper.back();
}
global = updateLocalTextSearch(global, chatId, threadId, false); global = updateLocalTextSearch(global, chatId, threadId, false);
global = replaceLocalTextSearchResults(global, chatId, threadId, undefined); global = replaceLocalTextSearchResults(global, chatId, threadId, undefined);
return global; return global;

View File

@ -1,7 +1,7 @@
import { addReducer, getGlobal, setGlobal } from '../../../lib/teact/teactn'; import { addReducer, getGlobal, setGlobal } from '../../../lib/teact/teactn';
import { MAIN_THREAD_ID } from '../../../api/types'; import { MAIN_THREAD_ID } from '../../../api/types';
import { FocusDirection, RightColumnContent } from '../../../types'; import { FocusDirection } from '../../../types';
import { import {
enterMessageSelectMode, enterMessageSelectMode,
@ -24,7 +24,6 @@ import {
selectForwardedMessageIdsByGroupId, selectIsViewportNewest, selectReplyingToId, selectForwardedMessageIdsByGroupId, selectIsViewportNewest, selectReplyingToId,
} from '../../selectors'; } from '../../selectors';
import { findLast } from '../../../util/iteratees'; import { findLast } from '../../../util/iteratees';
import { HistoryWrapper } from '../../../util/history';
const FOCUS_DURATION = 2000; const FOCUS_DURATION = 2000;
const POLL_RESULT_OPEN_DELAY_MS = 450; const POLL_RESULT_OPEN_DELAY_MS = 450;
@ -175,18 +174,11 @@ addReducer('closeAudioPlayer', (global) => {
}); });
addReducer('openPollResults', (global, actions, payload) => { addReducer('openPollResults', (global, actions, payload) => {
const { chatId, messageId, noPushState } = payload!; const { chatId, messageId } = payload!;
const shouldOpenInstantly = selectIsRightColumnShown(global); const shouldOpenInstantly = selectIsRightColumnShown(global);
if (!noPushState) { if (!shouldOpenInstantly) {
HistoryWrapper.pushState({
type: 'right',
contentKey: RightColumnContent.PollResults,
});
}
if (shouldOpenInstantly) {
window.setTimeout(() => { window.setTimeout(() => {
const newGlobal = getGlobal(); const newGlobal = getGlobal();
@ -211,13 +203,7 @@ addReducer('openPollResults', (global, actions, payload) => {
} }
}); });
addReducer('closePollResults', (global, actions, payload) => { addReducer('closePollResults', (global) => {
const { noPushState } = payload;
if (!noPushState) {
HistoryWrapper.back();
}
setGlobal({ setGlobal({
...global, ...global,
pollResults: {}, pollResults: {},

View File

@ -4,52 +4,24 @@ import { GlobalState } from '../../../global/types';
import { IS_MOBILE_SCREEN } from '../../../util/environment'; import { IS_MOBILE_SCREEN } from '../../../util/environment';
import getReadableErrorText from '../../../util/getReadableErrorText'; import getReadableErrorText from '../../../util/getReadableErrorText';
import { selectCurrentMessageList, selectRightColumnContentKey } from '../../selectors'; import { selectCurrentMessageList } from '../../selectors';
import { HistoryWrapper } from '../../../util/history';
const MAX_STORED_EMOJIS = 18; // Represents two rows of recent emojis const MAX_STORED_EMOJIS = 18; // Represents two rows of recent emojis
addReducer('toggleChatInfo', (global, actions, payload) => { addReducer('toggleChatInfo', (global) => {
const { noPushState } = payload;
if (!noPushState) {
if (global.isChatInfoShown) {
HistoryWrapper.back();
} else {
HistoryWrapper.pushState({
type: 'right',
contentKey: selectRightColumnContentKey(global),
});
}
}
return { return {
...global, ...global,
isChatInfoShown: !global.isChatInfoShown, isChatInfoShown: !global.isChatInfoShown,
}; };
}); });
addReducer('toggleManagement', (global, actions, payload): GlobalState | undefined => { addReducer('toggleManagement', (global): GlobalState | undefined => {
const { chatId } = selectCurrentMessageList(global) || {}; const { chatId } = selectCurrentMessageList(global) || {};
const { noPushState } = payload;
if (!chatId) { if (!chatId) {
return undefined; return undefined;
} }
const { isActive: prevIsActive } = global.management.byChatId[chatId] || {};
if (!noPushState) {
if (prevIsActive) {
HistoryWrapper.back();
} else {
HistoryWrapper.pushState({
type: 'right',
contentKey: selectRightColumnContentKey(global),
});
}
}
return { return {
...global, ...global,
management: { management: {
@ -57,7 +29,7 @@ addReducer('toggleManagement', (global, actions, payload): GlobalState | undefin
...global.management.byChatId, ...global.management.byChatId,
[chatId]: { [chatId]: {
...global.management.byChatId[chatId], ...global.management.byChatId[chatId],
isActive: !prevIsActive, isActive: !(global.management.byChatId[chatId] || {}).isActive,
}, },
}, },
}, },

View File

@ -1,21 +1,7 @@
import { addReducer } from '../../../lib/teact/teactn'; import { addReducer } from '../../../lib/teact/teactn';
import { HistoryWrapper } from '../../../util/history';
import { RightColumnContent } from '../../../types';
addReducer('setStickerSearchQuery', (global, actions, payload) => { addReducer('setStickerSearchQuery', (global, actions, payload) => {
const { query, noPushState } = payload!; const { query } = payload!;
const previousQuery = global.stickers.search.query;
if (!noPushState && previousQuery !== query) {
if (query !== undefined && previousQuery === undefined) {
HistoryWrapper.pushState({
type: 'right',
contentKey: RightColumnContent.StickerSearch,
});
} else {
HistoryWrapper.back();
}
}
return { return {
...global, ...global,
@ -30,19 +16,7 @@ addReducer('setStickerSearchQuery', (global, actions, payload) => {
}); });
addReducer('setGifSearchQuery', (global, actions, payload) => { addReducer('setGifSearchQuery', (global, actions, payload) => {
const { query, noPushState } = payload!; const { query } = payload!;
const previousQuery = global.gifs.search.query;
if (!noPushState && previousQuery !== query) {
if (query !== undefined) {
HistoryWrapper.pushState({
type: 'right',
contentKey: RightColumnContent.GifSearch,
});
} else {
HistoryWrapper.back();
}
}
return { return {
...global, ...global,

View File

@ -65,7 +65,6 @@
// Used by ChatList and ContactList components // Used by ChatList and ContactList components
.chat-list { .chat-list {
background: var(--color-background);
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
padding: .5rem .125rem .5rem .4375rem; padding: .5rem .125rem .5rem .4375rem;

View File

@ -1,20 +0,0 @@
export const HistoryWrapper: {
pushState(data: any): void;
back(): void;
states: any[];
isHistoryChangedByUser: boolean;
} = {
states: [],
isHistoryChangedByUser: true,
pushState(data: any) {
this.states.push(data);
window.history.pushState(data, '');
},
back() {
this.isHistoryChangedByUser = false;
window.history.back();
this.states.pop();
},
};