Simple browser history support

This commit is contained in:
Alexander Zinchuk 2021-04-19 18:36:58 +03:00
parent b7f776593e
commit 7484124533
5 changed files with 49 additions and 4 deletions

View File

@ -11,6 +11,7 @@ import { pick } from '../../util/iteratees';
import InputText from '../ui/InputText';
import Loading from '../ui/Loading';
import TrackingMonkey from '../common/TrackingMonkey';
import useHistoryBack from '../../hooks/useHistoryBack';
type StateProps = Pick<GlobalState, 'authPhoneNumber' | 'authIsCodeViaApp' | 'authIsLoading' | 'authError'>;
type DispatchProps = Pick<GlobalActions, 'setAuthCode' | 'returnToAuthPhoneNumber' | 'clearAuthError'>;
@ -33,6 +34,8 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
}
}, []);
useHistoryBack(returnToAuthPhoneNumber);
const onCodeChange = useCallback((e: FormEvent<HTMLInputElement>) => {
if (authError) {
clearAuthError();
@ -77,7 +80,7 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
{authPhoneNumber}
<div
className="auth-number-edit"
onClick={() => returnToAuthPhoneNumber()}
onClick={returnToAuthPhoneNumber}
role="button"
tabIndex={0}
title="Sign In with another phone number"

View File

@ -10,6 +10,7 @@ import { pick } from '../../util/iteratees';
import Loading from '../ui/Loading';
import Button from '../ui/Button';
import buildClassName from '../../util/buildClassName';
import useHistoryBack from '../../hooks/useHistoryBack';
type StateProps = Pick<GlobalState, 'connectionState' | 'authQrCode'>;
type DispatchProps = Pick<GlobalActions, 'returnToAuthPhoneNumber'>;
@ -40,6 +41,8 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
}, container);
}, [connectionState, authQrCode]);
useHistoryBack(returnToAuthPhoneNumber);
return (
<div id="auth-qr-form" className="custom-scroll">
<div className="auth-form">

View File

@ -3,10 +3,16 @@ import { addReducer } from '../lib/teact/teactn';
import { INITIAL_STATE } from './initial';
import { initCache, loadCache } from './cache';
import { cloneDeep } from '../util/iteratees';
import { selectCurrentMessageList } from '../modules/selectors';
initCache();
addReducer('init', () => {
const initial = cloneDeep(INITIAL_STATE);
return loadCache(initial) || initial;
const newGlobal = loadCache(initial) || initial;
const currentMessageList = selectCurrentMessageList(newGlobal) || {};
window.history.replaceState(currentMessageList, '');
return newGlobal;
});

View File

@ -0,0 +1,15 @@
// This is unsafe and can be not chained as `popstate` event is asynchronous
export default function useHistoryBack(handler: NoneToVoidFunction) {
function handlePopState() {
handler();
}
window.addEventListener('popstate', handlePopState);
window.history.pushState({}, '');
return () => {
window.removeEventListener('popstate', handlePopState);
window.history.back();
};
}

View File

@ -1,12 +1,26 @@
import { addReducer, setGlobal } from '../../../lib/teact/teactn';
import { addReducer, getDispatch, setGlobal } from '../../../lib/teact/teactn';
import {
exitMessageSelectMode,
updateCurrentMessageList,
} from '../../reducers';
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 { id, threadId, type } = payload!;
const {
id, threadId = -1, type = 'thread', noPushState,
} = payload!;
const currentMessageList = selectCurrentMessageList(global);
@ -30,6 +44,10 @@ addReducer('openChat', (global, actions, payload) => {
};
setGlobal(global);
if (!noPushState) {
window.history.pushState({ chatId: id, threadId, messageListType: type }, '');
}
}
return updateCurrentMessageList(global, id, threadId, type);