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

View File

@ -11,18 +11,14 @@ import Loading from '../ui/Loading';
import Button from '../ui/Button';
import buildClassName from '../../util/buildClassName';
import useHistoryBack from '../../hooks/useHistoryBack';
import { HistoryWrapper } from '../../util/history';
type StateProps = Pick<GlobalState, 'connectionState' | 'authQrCode'>;
type DispatchProps = Pick<GlobalActions, 'returnToAuthPhoneNumber' | 'setShouldSkipUiLoaderTransition'>;
type DispatchProps = Pick<GlobalActions, 'returnToAuthPhoneNumber'>;
const DATA_PREFIX = 'tg://login?token=';
const AuthCode: FC<StateProps & DispatchProps> = ({
connectionState,
authQrCode,
returnToAuthPhoneNumber,
setShouldSkipUiLoaderTransition,
connectionState, authQrCode, returnToAuthPhoneNumber,
}) => {
// eslint-disable-next-line no-null/no-null
const qrCodeRef = useRef<HTMLDivElement>(null);
@ -45,15 +41,7 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
}, container);
}, [connectionState, authQrCode]);
const handleBackToPhoneNumber = () => {
HistoryWrapper.back();
returnToAuthPhoneNumber();
};
useHistoryBack((event, noAnimation) => {
setShouldSkipUiLoaderTransition({ shouldSkipUiLoaderTransition: noAnimation });
returnToAuthPhoneNumber();
});
useHistoryBack(returnToAuthPhoneNumber);
return (
<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>Point your phone at this screen to confirm login</span></li>
</ol>
<Button isText onClick={handleBackToPhoneNumber}>Log in by phone number</Button>
<Button isText onClick={returnToAuthPhoneNumber}>Log in by phone number</Button>
</div>
</div>
);
@ -75,5 +63,5 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal(
(global): StateProps => pick(global, ['connectionState', 'authQrCode']),
(setGlobal, actions): DispatchProps => pick(actions, ['returnToAuthPhoneNumber', 'setShouldSkipUiLoaderTransition']),
(setGlobal, actions): DispatchProps => pick(actions, ['returnToAuthPhoneNumber']),
)(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 useFlag from '../../hooks/useFlag';
import useShowTransition from '../../hooks/useShowTransition';
import useOnChange from '../../hooks/useOnChange';
import { pause } from '../../util/schedulers';
import { preloadImage } from '../../util/files';
import preloadFonts from '../../util/fonts';
@ -29,18 +28,17 @@ type OwnProps = {
children: any;
};
type StateProps = Pick<GlobalState, 'uiReadyState' | 'shouldSkipUiLoaderTransition'> & {
type StateProps = Pick<GlobalState, 'uiReadyState'> & {
hasCustomBackground?: boolean;
hasCustomBackgroundColor: boolean;
isRightColumnShown?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'setIsUiReady' | 'setShouldSkipUiLoaderTransition'>;
type DispatchProps = Pick<GlobalActions, 'setIsUiReady'>;
const MAX_PRELOAD_DELAY = 700;
const SECOND_STATE_DELAY = 1000;
const AVATARS_TO_PRELOAD = 10;
const TRANSITION_TIME = 400;
function preloadAvatars() {
const { listIds, byId } = getGlobal().chats;
@ -84,9 +82,7 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
hasCustomBackground,
hasCustomBackgroundColor,
isRightColumnShown,
shouldSkipUiLoaderTransition,
setIsUiReady,
setShouldSkipUiLoaderTransition,
}) => {
const [isReady, markReady] = useFlag();
const {
@ -127,18 +123,10 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useOnChange(() => {
if (shouldSkipUiLoaderTransition) {
setTimeout(() => {
setShouldSkipUiLoaderTransition({ shouldSkipUiLoaderTransition: false });
}, TRANSITION_TIME);
}
}, [shouldSkipUiLoaderTransition]);
return (
<div id="UiLoader">
{children}
{shouldRenderMask && !shouldSkipUiLoaderTransition && (
{shouldRenderMask && (
<div className={buildClassName('mask', transitionClassNames)}>
{page === 'main' ? (
<>
@ -168,12 +156,11 @@ export default withGlobal<OwnProps>(
const { background, backgroundColor } = global.settings.themes[theme] || {};
return {
shouldSkipUiLoaderTransition: global.shouldSkipUiLoaderTransition,
uiReadyState: global.uiReadyState,
hasCustomBackground: Boolean(background),
hasCustomBackgroundColor: Boolean(backgroundColor),
isRightColumnShown: selectIsRightColumnShown(global),
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setIsUiReady', 'setShouldSkipUiLoaderTransition']),
(setGlobal, actions): DispatchProps => pick(actions, ['setIsUiReady']),
)(UiLoader);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -87,14 +87,6 @@
overflow: hidden;
}
}
#Main.history-animation-disabled & {
transition: none;
&:after {
transition: none;
}
}
}
@media (max-width: 600px) {
@ -112,18 +104,6 @@
@media (max-width: 600px) {
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 {
@ -175,14 +155,6 @@
transform: translate3d(-20vw, 0, 0);
}
}
#Main.history-animation-disabled & {
transition: none;
&:after {
transition: none;
}
}
}
.SymbolMenu {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,60 +1,15 @@
// This is unsafe and can be not chained as `popstate` event is asynchronous
import { useEffect } from '../lib/teact/teact';
import { IS_IOS } from '../util/environment';
import { HistoryWrapper } from '../util/history';
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;
export default function useHistoryBack(handler: NoneToVoidFunction) {
function handlePopState() {
handler();
}
};
const onTouchEnd = () => {
if (isEdge) {
setTimeout(() => {
isEdge = false;
}, SAFARI_EDGE_BACK_GESTURE_DURATION);
}
};
window.addEventListener('popstate', handlePopState);
window.history.pushState({}, '');
if (IS_IOS) {
// eslint-disable-next-line no-console
console.log('Adding event listeners for useHistoryBack');
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]);
return () => {
window.removeEventListener('popstate', handlePopState);
window.history.back();
};
useEffect(() => {
window.addEventListener('popstate', onPopState);
return () => {
window.removeEventListener('popstate', onPopState);
};
});
}

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,6 @@ import {
} from '../../../util/environment';
import { setLanguage } from '../../../util/langProvider';
import switchTheme from '../../../util/switchTheme';
import { HistoryWrapper } from '../../../util/history';
addReducer('init', (global) => {
const {
@ -46,11 +45,6 @@ addReducer('setIsUiReady', (global, actions, payload) => {
addReducer('setAuthPhoneNumber', (global, actions, payload) => {
const { phoneNumber } = payload!;
HistoryWrapper.pushState({
type: 'login',
contentKey: 'authCode',
});
return {
...global,
authPhoneNumber: phoneNumber,
@ -70,12 +64,3 @@ addReducer('clearAuthError', (global) => {
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 { selectCurrentMessageList } from '../../selectors';
import { buildChatThreadKey } from '../../helpers';
import { HistoryWrapper } from '../../../util/history';
import { RightColumnContent } from '../../../types';
addReducer('openLocalTextSearch', (global) => {
const { chatId, threadId } = selectCurrentMessageList(global) || {};
@ -17,25 +15,15 @@ addReducer('openLocalTextSearch', (global) => {
return undefined;
}
HistoryWrapper.pushState({
type: 'right',
contentKey: RightColumnContent.Search,
});
return updateLocalTextSearch(global, chatId, threadId, true);
});
addReducer('closeLocalTextSearch', (global, actions, payload) => {
const { noPushState } = payload;
addReducer('closeLocalTextSearch', (global) => {
const { chatId, threadId } = selectCurrentMessageList(global) || {};
if (!chatId || !threadId) {
return undefined;
}
if (!noPushState) {
HistoryWrapper.back();
}
global = updateLocalTextSearch(global, chatId, threadId, false);
global = replaceLocalTextSearchResults(global, chatId, threadId, undefined);
return global;

View File

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

View File

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

View File

@ -65,7 +65,6 @@
// Used by ChatList and ContactList components
.chat-list {
background: var(--color-background);
height: 100%;
overflow-y: auto;
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();
},
};