Main Menu: Fix switching to other web versions (#1270)

This commit is contained in:
Alexander Zinchuk 2021-07-14 14:13:08 +03:00
parent c63b74a42d
commit 02c805cb6c
2 changed files with 48 additions and 28 deletions

View File

@ -18,6 +18,7 @@ import { formatDateToString } from '../../../util/dateFormat';
import { selectTheme } from '../../../modules/selectors'; import { selectTheme } from '../../../modules/selectors';
import switchTheme from '../../../util/switchTheme'; import switchTheme from '../../../util/switchTheme';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import { disableHistoryBack } from '../../../hooks/useHistoryBack';
import DropdownMenu from '../../ui/DropdownMenu'; import DropdownMenu from '../../ui/DropdownMenu';
import MenuItem from '../../ui/MenuItem'; import MenuItem from '../../ui/MenuItem';
@ -162,6 +163,7 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
const handleSwitchToWebK = () => { const handleSwitchToWebK = () => {
localStorage.setItem(PERMANENT_VERSION_KEY, JSON.stringify('K')); localStorage.setItem(PERMANENT_VERSION_KEY, JSON.stringify('K'));
disableHistoryBack();
}; };
const isSearchFocused = ( const isSearchFocused = (
@ -255,6 +257,7 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
<MenuItem <MenuItem
icon="char-W" icon="char-W"
href={LEGACY_VERSION_URL} href={LEGACY_VERSION_URL}
onClick={disableHistoryBack}
> >
Switch to Old Version Switch to Old Version
</MenuItem> </MenuItem>

View File

@ -9,20 +9,40 @@ import { getDispatch } from '../lib/teact/teactn';
const SAFARI_EDGE_BACK_GESTURE_LIMIT = 300; const SAFARI_EDGE_BACK_GESTURE_LIMIT = 300;
const SAFARI_EDGE_BACK_GESTURE_DURATION = 350; const SAFARI_EDGE_BACK_GESTURE_DURATION = 350;
let isEdge = false; type HistoryState = {
currentIndex: number;
nextStateIndexToReplace: number;
isHistoryAltered: boolean;
isDisabled: boolean;
isEdge: boolean;
currentIndexes: number[];
};
const historyState: HistoryState = {
currentIndex: 0,
nextStateIndexToReplace: -1,
isHistoryAltered: false,
isDisabled: false,
isEdge: false,
currentIndexes: [],
};
export const disableHistoryBack = () => {
historyState.isDisabled = true;
};
const handleTouchStart = (event: TouchEvent) => { const handleTouchStart = (event: TouchEvent) => {
const x = event.touches[0].pageX; const x = event.touches[0].pageX;
if (x <= SAFARI_EDGE_BACK_GESTURE_LIMIT || x >= window.innerWidth - SAFARI_EDGE_BACK_GESTURE_LIMIT) { if (x <= SAFARI_EDGE_BACK_GESTURE_LIMIT || x >= window.innerWidth - SAFARI_EDGE_BACK_GESTURE_LIMIT) {
isEdge = true; historyState.isEdge = true;
} }
}; };
const handleTouchEnd = () => { const handleTouchEnd = () => {
if (isEdge) { if (historyState.isEdge) {
setTimeout(() => { setTimeout(() => {
isEdge = false; historyState.isEdge = false;
}, SAFARI_EDGE_BACK_GESTURE_DURATION); }, SAFARI_EDGE_BACK_GESTURE_DURATION);
} }
}; };
@ -33,12 +53,7 @@ if (IS_IOS) {
window.addEventListener('popstate', handleTouchEnd); window.addEventListener('popstate', handleTouchEnd);
} }
let currentIndex = 0; window.history.replaceState({ index: historyState.currentIndex }, '');
let nextStateIndexToReplace = -1;
let isHistoryAltered = false;
const currentIndexes: number[] = [];
window.history.replaceState({ index: currentIndex }, '');
export default function useHistoryBack( export default function useHistoryBack(
isActive: boolean | undefined, isActive: boolean | undefined,
@ -54,53 +69,55 @@ export default function useHistoryBack(
useEffect(() => { useEffect(() => {
const handlePopState = (event: PopStateEvent) => { const handlePopState = (event: PopStateEvent) => {
if (isHistoryAltered) { if (historyState.isHistoryAltered) {
setTimeout(() => { setTimeout(() => {
isHistoryAltered = false; historyState.isHistoryAltered = false;
}, 0); }, 0);
return; return;
} }
const { index: i } = event.state; const { index: i } = event.state;
const index = i || 0; const index = i || 0;
const prev = currentIndexes[currentIndexes.indexOf(indexRef.current) - 1]; const prev = historyState.currentIndexes[historyState.currentIndexes.indexOf(indexRef.current) - 1];
if (historyState.isDisabled) return;
if (!isClosed.current && (index === 0 || index === prev)) { if (!isClosed.current && (index === 0 || index === prev)) {
currentIndexes.splice(currentIndexes.indexOf(indexRef.current), 1); historyState.currentIndexes.splice(historyState.currentIndexes.indexOf(indexRef.current), 1);
if (onBack) { if (onBack) {
if (isEdge) { if (historyState.isEdge) {
getDispatch().disableHistoryAnimations(); getDispatch().disableHistoryAnimations();
} }
onBack(!isEdge); onBack(!historyState.isEdge);
isClosed.current = true; isClosed.current = true;
} }
} else if (index === indexRef.current && isClosed.current && onForward) { } else if (index === indexRef.current && isClosed.current && onForward) {
isForward.current = true; isForward.current = true;
if (isEdge) { if (historyState.isEdge) {
getDispatch().disableHistoryAnimations(); getDispatch().disableHistoryAnimations();
} }
onForward(event.state.state); onForward(event.state.state);
} }
}; };
if (prevIsActive !== isActive) { if (!historyState.isDisabled && prevIsActive !== isActive) {
if (isActive) { if (isActive) {
isClosed.current = false; isClosed.current = false;
if (isForward.current) { if (isForward.current) {
isForward.current = false; isForward.current = false;
currentIndexes.push(indexRef.current); historyState.currentIndexes.push(indexRef.current);
} else { } else {
setTimeout(() => { setTimeout(() => {
const index = ++currentIndex; const index = ++historyState.currentIndex;
currentIndexes.push(index); historyState.currentIndexes.push(index);
window.history[ window.history[
(currentIndexes.includes(nextStateIndexToReplace - 1) (historyState.currentIndexes.includes(historyState.nextStateIndexToReplace - 1)
&& window.history.state.index !== 0 && window.history.state.index !== 0
&& nextStateIndexToReplace === index && historyState.nextStateIndexToReplace === index
&& !shouldReplaceNext) && !shouldReplaceNext)
? 'replaceState' ? 'replaceState'
: 'pushState' : 'pushState'
@ -112,20 +129,20 @@ export default function useHistoryBack(
indexRef.current = index; indexRef.current = index;
if (shouldReplaceNext) { if (shouldReplaceNext) {
nextStateIndexToReplace = currentIndex + 1; historyState.nextStateIndexToReplace = historyState.currentIndex + 1;
} }
}, 0); }, 0);
} }
} else if (!isClosed.current) { } else if (!isClosed.current) {
if (indexRef.current === currentIndex || !shouldReplaceNext) { if (indexRef.current === historyState.currentIndex || !shouldReplaceNext) {
isHistoryAltered = true; historyState.isHistoryAltered = true;
window.history.back(); window.history.back();
setTimeout(() => { setTimeout(() => {
nextStateIndexToReplace = -1; historyState.nextStateIndexToReplace = -1;
}, 400); }, 400);
} }
currentIndexes.splice(currentIndexes.indexOf(indexRef.current), 1); historyState.currentIndexes.splice(historyState.currentIndexes.indexOf(indexRef.current), 1);
isClosed.current = true; isClosed.current = true;
} }