Use global navigation history stack

The readers history stack was different to the one from the rest of the app, resulting in an infinite loop when using the closing the reader and using the back button in the manga page, since the back button just opened the reader again.

Regression introduced with 4bb458778e
This commit is contained in:
schroda
2024-06-14 13:32:54 +02:00
parent 7266270075
commit 7337c18c7b
4 changed files with 26 additions and 9 deletions

View File

@@ -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<React.SetStateAction<string | undefined>>;
@@ -28,6 +30,7 @@ type ContextType = {
};
export const NavBarContext = React.createContext<ContextType>({
history: [],
defaultBackTo: undefined,
setDefaultBackTo: (): void => {},
title: 'Suwayomi',

View File

@@ -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: <div />,
});
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 <NavBarContext.Provider value={value}>{children}</NavBarContext.Provider>;
}

View File

@@ -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;

View File

@@ -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<string[]>([]);
const [history, setHistory] = useState<string[]>([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}"`);