From 02c805cb6c04d15ea466d89615220a4357f7503c Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Wed, 14 Jul 2021 14:13:08 +0300 Subject: [PATCH] Main Menu: Fix switching to other web versions (#1270) --- src/components/left/main/LeftMainHeader.tsx | 3 + src/hooks/useHistoryBack.ts | 73 +++++++++++++-------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/components/left/main/LeftMainHeader.tsx b/src/components/left/main/LeftMainHeader.tsx index 3eeff7586..182b78183 100644 --- a/src/components/left/main/LeftMainHeader.tsx +++ b/src/components/left/main/LeftMainHeader.tsx @@ -18,6 +18,7 @@ import { formatDateToString } from '../../../util/dateFormat'; import { selectTheme } from '../../../modules/selectors'; import switchTheme from '../../../util/switchTheme'; import useLang from '../../../hooks/useLang'; +import { disableHistoryBack } from '../../../hooks/useHistoryBack'; import DropdownMenu from '../../ui/DropdownMenu'; import MenuItem from '../../ui/MenuItem'; @@ -162,6 +163,7 @@ const LeftMainHeader: FC = ({ const handleSwitchToWebK = () => { localStorage.setItem(PERMANENT_VERSION_KEY, JSON.stringify('K')); + disableHistoryBack(); }; const isSearchFocused = ( @@ -255,6 +257,7 @@ const LeftMainHeader: FC = ({ Switch to Old Version diff --git a/src/hooks/useHistoryBack.ts b/src/hooks/useHistoryBack.ts index cf9f546eb..880574333 100644 --- a/src/hooks/useHistoryBack.ts +++ b/src/hooks/useHistoryBack.ts @@ -9,20 +9,40 @@ import { getDispatch } from '../lib/teact/teactn'; const SAFARI_EDGE_BACK_GESTURE_LIMIT = 300; 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 x = event.touches[0].pageX; if (x <= SAFARI_EDGE_BACK_GESTURE_LIMIT || x >= window.innerWidth - SAFARI_EDGE_BACK_GESTURE_LIMIT) { - isEdge = true; + historyState.isEdge = true; } }; const handleTouchEnd = () => { - if (isEdge) { + if (historyState.isEdge) { setTimeout(() => { - isEdge = false; + historyState.isEdge = false; }, SAFARI_EDGE_BACK_GESTURE_DURATION); } }; @@ -33,12 +53,7 @@ if (IS_IOS) { window.addEventListener('popstate', handleTouchEnd); } -let currentIndex = 0; -let nextStateIndexToReplace = -1; -let isHistoryAltered = false; -const currentIndexes: number[] = []; - -window.history.replaceState({ index: currentIndex }, ''); +window.history.replaceState({ index: historyState.currentIndex }, ''); export default function useHistoryBack( isActive: boolean | undefined, @@ -54,53 +69,55 @@ export default function useHistoryBack( useEffect(() => { const handlePopState = (event: PopStateEvent) => { - if (isHistoryAltered) { + if (historyState.isHistoryAltered) { setTimeout(() => { - isHistoryAltered = false; + historyState.isHistoryAltered = false; }, 0); return; } const { index: i } = event.state; 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)) { - currentIndexes.splice(currentIndexes.indexOf(indexRef.current), 1); + historyState.currentIndexes.splice(historyState.currentIndexes.indexOf(indexRef.current), 1); if (onBack) { - if (isEdge) { + if (historyState.isEdge) { getDispatch().disableHistoryAnimations(); } - onBack(!isEdge); + onBack(!historyState.isEdge); isClosed.current = true; } } else if (index === indexRef.current && isClosed.current && onForward) { isForward.current = true; - if (isEdge) { + if (historyState.isEdge) { getDispatch().disableHistoryAnimations(); } onForward(event.state.state); } }; - if (prevIsActive !== isActive) { + if (!historyState.isDisabled && prevIsActive !== isActive) { if (isActive) { isClosed.current = false; if (isForward.current) { isForward.current = false; - currentIndexes.push(indexRef.current); + historyState.currentIndexes.push(indexRef.current); } else { setTimeout(() => { - const index = ++currentIndex; + const index = ++historyState.currentIndex; - currentIndexes.push(index); + historyState.currentIndexes.push(index); window.history[ - (currentIndexes.includes(nextStateIndexToReplace - 1) + (historyState.currentIndexes.includes(historyState.nextStateIndexToReplace - 1) && window.history.state.index !== 0 - && nextStateIndexToReplace === index + && historyState.nextStateIndexToReplace === index && !shouldReplaceNext) ? 'replaceState' : 'pushState' @@ -112,20 +129,20 @@ export default function useHistoryBack( indexRef.current = index; if (shouldReplaceNext) { - nextStateIndexToReplace = currentIndex + 1; + historyState.nextStateIndexToReplace = historyState.currentIndex + 1; } }, 0); } } else if (!isClosed.current) { - if (indexRef.current === currentIndex || !shouldReplaceNext) { - isHistoryAltered = true; + if (indexRef.current === historyState.currentIndex || !shouldReplaceNext) { + historyState.isHistoryAltered = true; window.history.back(); setTimeout(() => { - nextStateIndexToReplace = -1; + historyState.nextStateIndexToReplace = -1; }, 400); } - currentIndexes.splice(currentIndexes.indexOf(indexRef.current), 1); + historyState.currentIndexes.splice(historyState.currentIndexes.indexOf(indexRef.current), 1); isClosed.current = true; }