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:
@@ -10,6 +10,8 @@ import React, { useContext, useEffect } from 'react';
|
|||||||
import { INavbarOverride } from '@/typings';
|
import { INavbarOverride } from '@/typings';
|
||||||
|
|
||||||
type ContextType = {
|
type ContextType = {
|
||||||
|
history: string[];
|
||||||
|
|
||||||
// Default back button url
|
// Default back button url
|
||||||
defaultBackTo: string | undefined;
|
defaultBackTo: string | undefined;
|
||||||
setDefaultBackTo: React.Dispatch<React.SetStateAction<string | undefined>>;
|
setDefaultBackTo: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||||
@@ -28,6 +30,7 @@ type ContextType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const NavBarContext = React.createContext<ContextType>({
|
export const NavBarContext = React.createContext<ContextType>({
|
||||||
|
history: [],
|
||||||
defaultBackTo: undefined,
|
defaultBackTo: undefined,
|
||||||
setDefaultBackTo: (): void => {},
|
setDefaultBackTo: (): void => {},
|
||||||
title: 'Suwayomi',
|
title: 'Suwayomi',
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { INavbarOverride } from '@/typings';
|
import { INavbarOverride } from '@/typings';
|
||||||
import { NavBarContext } from '@/components/context/NavbarContext';
|
import { NavBarContext } from '@/components/context/NavbarContext';
|
||||||
|
import { useHistory } from '@/util/useHistory.ts';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -23,6 +24,8 @@ export function NavBarContextProvider({ children }: IProps) {
|
|||||||
value: <div />,
|
value: <div />,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
const updateTitle = useCallback(
|
const updateTitle = useCallback(
|
||||||
(newTitle: string | React.ReactNode, browserTitle: string = typeof newTitle === 'string' ? newTitle : '') => {
|
(newTitle: string | React.ReactNode, browserTitle: string = typeof newTitle === 'string' ? newTitle : '') => {
|
||||||
document.title = `${browserTitle} - Suwayomi`;
|
document.title = `${browserTitle} - Suwayomi`;
|
||||||
@@ -33,6 +36,7 @@ export function NavBarContextProvider({ children }: IProps) {
|
|||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
history,
|
||||||
defaultBackTo,
|
defaultBackTo,
|
||||||
setDefaultBackTo,
|
setDefaultBackTo,
|
||||||
title,
|
title,
|
||||||
@@ -42,7 +46,7 @@ export function NavBarContextProvider({ children }: IProps) {
|
|||||||
override,
|
override,
|
||||||
setOverride,
|
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>;
|
return <NavBarContext.Provider value={value}>{children}</NavBarContext.Provider>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,12 @@
|
|||||||
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useHistory } from '@/util/useHistory.ts';
|
|
||||||
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
|
|
||||||
export const useBackButton = () => {
|
export const useBackButton = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const history = useHistory();
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { defaultBackTo: backToUrl } = useContext(NavBarContext);
|
const { history, defaultBackTo: backToUrl } = useContext(NavBarContext);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const isHistoryEmpty = !history.length;
|
const isHistoryEmpty = !history.length;
|
||||||
|
|||||||
@@ -6,14 +6,26 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* 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';
|
import { NavigationType, useLocation, useNavigationType } from 'react-router-dom';
|
||||||
|
|
||||||
|
const MAX_DEPTH = 50;
|
||||||
|
|
||||||
export const useHistory = () => {
|
export const useHistory = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigationType = useNavigationType();
|
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(() => {
|
useEffect(() => {
|
||||||
const isLastPageInHistory = location.key === 'default';
|
const isLastPageInHistory = location.key === 'default';
|
||||||
@@ -24,13 +36,13 @@ export const useHistory = () => {
|
|||||||
|
|
||||||
switch (navigationType) {
|
switch (navigationType) {
|
||||||
case NavigationType.Pop:
|
case NavigationType.Pop:
|
||||||
setHistory([...history.slice(0, -1)]);
|
updateHistory([...history.slice(0, -1)]);
|
||||||
break;
|
break;
|
||||||
case NavigationType.Push:
|
case NavigationType.Push:
|
||||||
setHistory([...history, location.pathname]);
|
updateHistory([...history, location.pathname]);
|
||||||
break;
|
break;
|
||||||
case NavigationType.Replace:
|
case NavigationType.Replace:
|
||||||
setHistory([...history.slice(0, -1), location.pathname]);
|
updateHistory([...history.slice(0, -1), location.pathname]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unexpected NavigationType "${navigationType}"`);
|
throw new Error(`Unexpected NavigationType "${navigationType}"`);
|
||||||
|
|||||||
Reference in New Issue
Block a user