Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix navbar back button behavior #195

Merged
merged 3 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/components/MangaCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useLocalStorage from 'util/useLocalStorage';
import SpinnerImage from 'components/util/SpinnerImage';
import { Box, styled } from '@mui/system';
import { useLibraryOptionsContext } from 'components/context/LibraryOptionsContext';
import { BACK } from 'util/useBackTo';

const BottomGradient = styled('div')({
position: 'absolute',
Expand Down Expand Up @@ -88,12 +89,14 @@ const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref)
const [useCache] = useLocalStorage<boolean>('useCache', true);
const [ItemWidth] = useLocalStorage<number>('ItemWidth', 300);

const mangaLinkTo = { pathname: `/manga/${id}/`, state: { backLink: BACK } };

if (gridLayout !== 2) {
const colomns = Math.round(dimensions / ItemWidth);
return (
// @ts-ignore gridsize type isnt allowed to be a decimal but it works fine
<Grid item xs={12 / colomns} sm={12 / colomns} md={12 / colomns} lg={12 / colomns}>
<Link to={`/manga/${id}/`} style={(gridLayout === 1) ? { textDecoration: 'none' } : {}}>
<Link to={mangaLinkTo} style={(gridLayout === 1) ? { textDecoration: 'none' } : {}}>
<Box
sx={{
display: 'flex',
Expand Down Expand Up @@ -190,7 +193,7 @@ const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref)
}
return (
<Grid item xs={12} sm={12} md={12} lg={12}>
<Link to={`/manga/${id}/`} style={{ textDecoration: 'none', color: 'unset' }}>
<Link to={mangaLinkTo} style={{ textDecoration: 'none', color: 'unset' }}>
<CardContent sx={{
display: 'flex',
justifyContent: 'space-between',
Expand Down
19 changes: 18 additions & 1 deletion src/components/context/NavbarContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import React from 'react';
import React, { useContext, useEffect } from 'react';

type ContextType = {
// Default back button url
defaultBackTo: string | undefined
setDefaultBackTo: React.Dispatch<React.SetStateAction<string | undefined>>

// AppBar title
title: string
setTitle: React.Dispatch<React.SetStateAction<string>>
Expand All @@ -22,6 +26,8 @@ type ContextType = {
};

const NavBarContext = React.createContext<ContextType>({
defaultBackTo: undefined,
setDefaultBackTo: ():void => {},
title: 'Tachidesk',
setTitle: ():void => {},
action: <div />,
Expand All @@ -31,3 +37,14 @@ const NavBarContext = React.createContext<ContextType>({
});

export default NavBarContext;

export const useNavBarContext = () => useContext(NavBarContext);

export const useSetDefaultBackTo = (value: string) => {
const { setDefaultBackTo } = useNavBarContext();

useEffect(() => {
setDefaultBackTo(value);
return () => setDefaultBackTo(undefined);
}, [value]);
};
3 changes: 2 additions & 1 deletion src/components/manga/ChapterCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Typography from '@mui/material/Typography';
import React from 'react';
import { Link } from 'react-router-dom';
import client from 'util/client';
import { BACK } from 'util/useBackTo';

interface IProps{
chapter: IChapter
Expand Down Expand Up @@ -118,7 +119,7 @@ const ChapterCard: React.FC<IProps> = (props: IProps) => {
}}
>
<Link
to={`/manga/${chapter.mangaId}/chapter/${chapter.index}`}
to={{ pathname: `/manga/${chapter.mangaId}/chapter/${chapter.index}`, state: { backLink: BACK } }}
style={{
textDecoration: 'none',
color: theme.palette.text[chapter.read ? 'disabled' : 'primary'],
Expand Down
3 changes: 2 additions & 1 deletion src/components/manga/ResumeFAB.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React from 'react';
import { Fab } from '@mui/material';
import { Link } from 'react-router-dom';
import { PlayArrow } from '@mui/icons-material';
import { BACK } from 'util/useBackTo';

interface ResumeFABProps{
chapter: IChapter
Expand All @@ -23,7 +24,7 @@ export default function ResumeFab(props: ResumeFABProps) {
component={Link}
variant="extended"
color="primary"
to={`/manga/${mangaId}/chapter/${index}/page/${lastPageRead}`}
to={{ pathname: `/manga/${mangaId}/chapter/${index}/page/${lastPageRead}`, state: { backLink: BACK } }}
>
<PlayArrow />
{index === 1 ? 'Start' : 'Resume' }
Expand Down
42 changes: 23 additions & 19 deletions src/components/navbar/DefaultNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ import GetAppIcon from '@mui/icons-material/GetApp';
import GetAppOutlinedIcon from '@mui/icons-material/GetAppOutlined';
import SettingsIcon from '@mui/icons-material/Settings';
import ArrowBack from '@mui/icons-material/ArrowBack';
import { useHistory } from 'react-router-dom';
import { Link, useHistory } from 'react-router-dom';
import NavBarContext from 'components/context/NavbarContext';
import DarkTheme from 'components/context/DarkTheme';
import ExtensionOutlinedIcon from 'components/util/CustomExtensionOutlinedIcon';
import { Box } from '@mui/system';
import { createPortal } from 'react-dom';
import useBackTo from 'util/useBackTo';
import DesktopSideBar from './navigation/DesktopSideBar';
import MobileBottomBar from './navigation/MobileBottomBar';

Expand Down Expand Up @@ -80,6 +81,7 @@ const navbarItems: Array<NavbarItem> = [

export default function DefaultNavBar() {
const { title, action, override } = useContext(NavBarContext);
const backTo = useBackTo();
const { darkTheme } = useContext(DarkTheme);

const theme = useTheme();
Expand All @@ -100,28 +102,30 @@ export default function DefaultNavBar() {
navbar = <DesktopSideBar navBarItems={navbarItems.filter((it) => it.show !== 'mobile')} />;
}

const handleBack = () => {
if (backTo.url != null) return;
history.goBack();
};

return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="fixed" color={darkTheme ? 'default' : 'primary'}>
<Toolbar>
{
!navbarItems.some(({ path }) => path === history.location.pathname)
&& (
<IconButton
edge="start"
sx={{ marginRight: theme.spacing(2) }}
color="inherit"
aria-label="menu"
disableRipple
// when page is opened in new tab backbutton will
// take you to the library
onClick={() => (history.length === 1 ? history.push('/library') : history.goBack())}
size="large"
>
<ArrowBack />
</IconButton>
)
}
{!isMainRoute && (
<IconButton
component={backTo.url ? Link : 'button'}
to={backTo.url}
edge="start"
sx={{ marginRight: theme.spacing(2) }}
color="inherit"
aria-label="menu"
disableRipple
size="large"
onClick={handleBack}
>
<ArrowBack />
</IconButton>
)}
<Typography variant={isMobileWidth ? 'h6' : 'h5'} sx={{ flexGrow: 1 }} noWrap textOverflow="ellipsis">
{title}
</Typography>
Expand Down
3 changes: 3 additions & 0 deletions src/components/navbar/NavBarContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface IProps{
}

export default function NavBarProvider({ children }:IProps) {
const [defaultBackTo, setDefaultBackTo] = useState<string | undefined>();
const [title, setTitle] = useState<string>('Tachidesk');
const [action, setAction] = useState<any>(<div />);
const [override, setOverride] = useState<INavbarOverride>({
Expand All @@ -21,6 +22,8 @@ export default function NavBarProvider({ children }:IProps) {
});

const value = {
defaultBackTo,
setDefaultBackTo,
title,
setTitle,
action,
Expand Down
14 changes: 11 additions & 3 deletions src/components/navbar/ReaderNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction';
import Collapse from '@mui/material/Collapse';
import Button from '@mui/material/Button';
import { styled } from '@mui/system';
import useBackTo from 'util/useBackTo';

const Root = styled('div')(({ theme }) => ({
top: 0,
Expand Down Expand Up @@ -129,6 +130,7 @@ interface IProps {

export default function ReaderNavBar(props: IProps) {
const history = useHistory();
const backTo = useBackTo();

const {
settings, setSettings, manga, chapter, curPage,
Expand Down Expand Up @@ -167,6 +169,12 @@ export default function ReaderNavBar(props: IProps) {
};
}, [handleScroll]);// handleScroll changes on every render

const handleClose = () => {
if (backTo.back) history.goBack();
else if (backTo.url) history.push(backTo.url);
else history.push(`/manga/${manga.id}`);
};

return (
<>
<Slide
Expand Down Expand Up @@ -203,7 +211,7 @@ export default function ReaderNavBar(props: IProps) {
color="inherit"
aria-label="menu"
disableRipple
onClick={() => history.push('..')}
onClick={handleClose}
size="large"
sx={{ mr: -1 }}
>
Expand Down Expand Up @@ -315,7 +323,7 @@ export default function ReaderNavBar(props: IProps) {
&& (
<Link
replace
to={`/manga/${manga.id}/chapter/${chapter.index - 1}`}
to={{ pathname: `/manga/${manga.id}/chapter/${chapter.index - 1}`, state: history.location.state }}
>
<Button
variant="outlined"
Expand All @@ -331,7 +339,7 @@ export default function ReaderNavBar(props: IProps) {
<Link
replace
style={{ gridArea: 'next' }}
to={`/manga/${manga.id}/chapter/${chapter.index + 1}`}
to={{ pathname: `/manga/${manga.id}/chapter/${chapter.index + 1}`, state: history.location.state }}
>
<Button
variant="outlined"
Expand Down
4 changes: 3 additions & 1 deletion src/screens/Manga.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
CircularProgress, IconButton, Stack, Tooltip,
} from '@mui/material';
import { Box } from '@mui/system';
import NavbarContext from 'components/context/NavbarContext';
import NavbarContext, { useSetDefaultBackTo } from 'components/context/NavbarContext';
import ChapterList from 'components/manga/ChapterList';
import { useRefreshManga } from 'components/manga/hooks';
import MangaDetails from 'components/manga/MangaDetails';
Expand All @@ -37,6 +37,8 @@ const Manga: React.FC = () => {

const [refresh, { loading: refreshing }] = useRefreshManga(id);

useSetDefaultBackTo(manga?.inLibrary === false && manga.sourceId != null ? `/sources/${manga.sourceId}/popular` : '/library');

useEffect(() => {
// Automatically fetch manga from source if data is older then 24 hours
// Automatic fetch is done only once, to prevent issues when server does
Expand Down
4 changes: 2 additions & 2 deletions src/screens/Reader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ export default function Reader() {
formData.append('read', 'true');
client.patch(`/api/v1/manga/${manga.id}/chapter/${chapter.index}`, formData);

history.replace(`/manga/${manga.id}/chapter/${chapter.index + 1}`);
history.replace({ pathname: `/manga/${manga.id}/chapter/${chapter.index + 1}`, state: history.location.state });
}
};

const prevChapter = () => {
if (chapter.index > 1) {
history.replace(`/manga/${manga.id}/chapter/${chapter.index - 1}`);
history.replace({ pathname: `/manga/${manga.id}/chapter/${chapter.index - 1}`, state: history.location.state });
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/screens/Updates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export default function Updates() {
transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
},
}}
onClick={() => history.push(`/manga/${chapter.mangaId}/chapter/${chapter.index}`)}
onClick={() => history.push({ pathname: `/manga/${chapter.mangaId}/chapter/${chapter.index}`, state: history.location.state })}
>
<CardContent sx={{
display: 'flex',
Expand Down
24 changes: 24 additions & 0 deletions src/util/useBackTo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import { useNavBarContext } from 'components/context/NavbarContext';
import { useLocation } from 'react-router-dom';

export const BACK = '__BACK__';

const useBackTo = (): { url?: string, back: boolean } => {
const location = useLocation<{ backLink?: string }>();
const { defaultBackTo } = useNavBarContext();

const url = location.state?.backLink ?? defaultBackTo;
return {
url: url === BACK ? undefined : url,
back: url === BACK,
};
};

export default useBackTo;