Revert "Better browser history support (#1125)"
This reverts commit 3c19438f1a9f6db9a06dc3b48bd06d062befe0b8.
This commit is contained in:
parent
70af1ed7f6
commit
c3201cf632
@ -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));
|
||||||
|
|||||||
@ -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 <b>Settings</b> > <b>Devices</b> > <b>Scan QR</b></span></li>
|
<li><span>Go to <b>Settings</b> > <b>Devices</b> > <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));
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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'}
|
||||||
|
|||||||
@ -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}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -19,10 +19,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.skip-slide-transition {
|
|
||||||
transition: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* scroll-slide
|
* scroll-slide
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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' |
|
||||||
|
|||||||
@ -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);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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',
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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: {},
|
||||||
|
|||||||
@ -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,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Loading…
x
Reference in New Issue
Block a user