diff --git a/src/components/context/NavbarContext.tsx b/src/components/context/NavbarContext.tsx index af7a8619..de65ebf6 100644 --- a/src/components/context/NavbarContext.tsx +++ b/src/components/context/NavbarContext.tsx @@ -10,6 +10,8 @@ import React, { useContext, useEffect } from 'react'; import { INavbarOverride } from '@/typings'; type ContextType = { + history: string[]; + // Default back button url defaultBackTo: string | undefined; setDefaultBackTo: React.Dispatch>; @@ -28,6 +30,7 @@ type ContextType = { }; export const NavBarContext = React.createContext({ + history: [], defaultBackTo: undefined, setDefaultBackTo: (): void => {}, title: 'Suwayomi', diff --git a/src/components/navbar/NavBarContextProvider.tsx b/src/components/navbar/NavBarContextProvider.tsx index ed6fca76..650ce310 100644 --- a/src/components/navbar/NavBarContextProvider.tsx +++ b/src/components/navbar/NavBarContextProvider.tsx @@ -9,6 +9,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { INavbarOverride } from '@/typings'; import { NavBarContext } from '@/components/context/NavbarContext'; +import { useHistory } from '@/util/useHistory.ts'; interface IProps { children: React.ReactNode; @@ -23,6 +24,8 @@ export function NavBarContextProvider({ children }: IProps) { value:
, }); + const history = useHistory(); + const updateTitle = useCallback( (newTitle: string | React.ReactNode, browserTitle: string = typeof newTitle === 'string' ? newTitle : '') => { document.title = `${browserTitle} - Suwayomi`; @@ -33,6 +36,7 @@ export function NavBarContextProvider({ children }: IProps) { const value = useMemo( () => ({ + history, defaultBackTo, setDefaultBackTo, title, @@ -42,7 +46,7 @@ export function NavBarContextProvider({ children }: IProps) { override, setOverride, }), - [defaultBackTo, setDefaultBackTo, title, updateTitle, action, setAction, override, setOverride], + [history, defaultBackTo, setDefaultBackTo, title, updateTitle, action, setAction, override, setOverride], ); return {children}; } diff --git a/src/util/useBackButton.ts b/src/util/useBackButton.ts index 7fe77e93..4641d179 100644 --- a/src/util/useBackButton.ts +++ b/src/util/useBackButton.ts @@ -8,14 +8,12 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { useContext } from 'react'; -import { useHistory } from '@/util/useHistory.ts'; import { NavBarContext } from '@/components/context/NavbarContext.tsx'; export const useBackButton = () => { const navigate = useNavigate(); - const history = useHistory(); const location = useLocation(); - const { defaultBackTo: backToUrl } = useContext(NavBarContext); + const { history, defaultBackTo: backToUrl } = useContext(NavBarContext); return () => { const isHistoryEmpty = !history.length; diff --git a/src/util/useHistory.ts b/src/util/useHistory.ts index 2aa9bf20..840a8eb5 100644 --- a/src/util/useHistory.ts +++ b/src/util/useHistory.ts @@ -6,14 +6,26 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { NavigationType, useLocation, useNavigationType } from 'react-router-dom'; +const MAX_DEPTH = 50; + export const useHistory = () => { const location = useLocation(); const navigationType = useNavigationType(); - const [history, setHistory] = useState([]); + const [history, setHistory] = useState([location.pathname]); + + const updateHistory = useCallback((newHistory: string[]) => { + // prevent the history from getting too large (only relevant in case the app never gets reloaded (e.g. browser F5, + // electron window gets closed)) + // theoretically the history should be empty for the "base" pages (e.g. library, updates, ...), but since the browser + // navigation is used, opening another base page pushes this page to this history, as if it had a different depth + // than the current page (expected history: library -> manga -> reader, + // possible history: library -> updates -> settings -> library -> manga -> reader) + setHistory(newHistory.slice(-MAX_DEPTH)); + }, []); useEffect(() => { const isLastPageInHistory = location.key === 'default'; @@ -24,13 +36,13 @@ export const useHistory = () => { switch (navigationType) { case NavigationType.Pop: - setHistory([...history.slice(0, -1)]); + updateHistory([...history.slice(0, -1)]); break; case NavigationType.Push: - setHistory([...history, location.pathname]); + updateHistory([...history, location.pathname]); break; case NavigationType.Replace: - setHistory([...history.slice(0, -1), location.pathname]); + updateHistory([...history.slice(0, -1), location.pathname]); break; default: throw new Error(`Unexpected NavigationType "${navigationType}"`);