Files
suwayomi-material-you-webui/src/components/navbar/ReaderNavBar.tsx

366 lines
14 KiB
TypeScript
Raw Normal View History

/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
2021-03-18 21:46:24 +03:30
* 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/. */
2021-09-09 17:51:22 +04:30
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
import React, { useEffect, useState } from 'react';
2021-09-09 17:51:22 +04:30
import Typography from '@mui/material/Typography';
2021-03-23 03:50:55 +04:30
import { useHistory, Link } from 'react-router-dom';
2021-09-09 17:51:22 +04:30
import Slide from '@mui/material/Slide';
import Fade from '@mui/material/Fade';
import Zoom from '@mui/material/Zoom';
import { Divider, Switch } from '@mui/material';
2021-09-09 17:51:22 +04:30
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import MenuItem from '@mui/material/MenuItem';
import Select from '@mui/material/Select';
import ListItemText from '@mui/material/ListItemText';
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,
left: 0,
width: '300px',
minWidth: '300px',
height: '100vh',
overflowY: 'auto',
backgroundColor: theme.palette.background.default,
'& header': {
backgroundColor: theme.palette.action.hover,
display: 'flex',
alignItems: 'center',
minHeight: '64px',
paddingLeft: '24px',
paddingRight: '24px',
transition: 'left 2s ease',
'& button': {
flexGrow: 0,
flexShrink: 0,
2021-03-23 03:50:55 +04:30
},
'& button:nth-child(1)': {
marginRight: '16px',
},
2021-03-23 03:50:55 +04:30
'& h1': {
fontSize: '1.25rem',
flexGrow: 1,
2021-03-23 03:50:55 +04:30
},
},
}));
const Navigation = styled('div')({
margin: '0 16px',
'& > span:nth-child(1)': {
textAlign: 'center',
display: 'block',
marginTop: '16px',
},
});
const ChapterNavigation = styled('div')({
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gridTemplateAreas: '"prev next"',
gridColumnGap: '5px',
margin: '10px 0',
'& a': {
flexGrow: 1,
textDecoration: 'none',
'& button': {
width: '100%',
padding: '5px 8px',
textTransform: 'none',
},
},
});
const OpenDrawerButton = styled(IconButton)(({ theme }) => ({
position: 'fixed',
top: 0 + 20,
left: 10 + 20,
height: '40px',
width: '40px',
borderRadius: 5,
backgroundColor: theme.palette.custom.main,
'&:hover': {
backgroundColor: theme.palette.custom.light,
},
}));
2021-03-18 21:46:24 +03:30
2021-03-19 14:52:20 +03:30
export const defaultReaderSettings = () => ({
staticNav: false,
showPageNumber: true,
2021-03-28 04:03:46 +04:30
continuesPageGap: false,
loadNextonEnding: false,
2021-05-15 23:22:37 +04:30
readerType: 'ContinuesVertical',
2021-03-19 14:52:20 +03:30
} as IReaderSettings);
2021-03-18 21:46:24 +03:30
interface IProps {
settings: IReaderSettings
setSettings: React.Dispatch<React.SetStateAction<IReaderSettings>>
2021-03-23 03:50:55 +04:30
manga: IManga | IMangaCard
chapter: IChapter
2021-03-23 03:50:55 +04:30
curPage: number
2021-03-18 21:46:24 +03:30
}
export default function ReaderNavBar(props: IProps) {
const history = useHistory();
const backTo = useBackTo();
2021-03-18 21:46:24 +03:30
2021-03-23 03:50:55 +04:30
const {
settings, setSettings, manga, chapter, curPage,
} = props;
2021-03-19 14:52:20 +03:30
const [drawerOpen, setDrawerOpen] = useState(false || settings.staticNav);
2021-03-18 21:46:24 +03:30
const [hideOpenButton, setHideOpenButton] = useState(false);
const [prevScrollPos, setPrevScrollPos] = useState(0);
2021-05-15 23:22:37 +04:30
const [settingsCollapseOpen, setSettingsCollapseOpen] = useState(true);
2021-03-18 21:46:24 +03:30
2021-03-19 14:52:20 +03:30
const setSettingValue = (key: string, value: any) => setSettings({ ...settings, [key]: value });
2021-03-18 21:46:24 +03:30
const handleScroll = () => {
const currentScrollPos = window.pageYOffset;
if (Math.abs(currentScrollPos - prevScrollPos) > 20) {
setHideOpenButton(currentScrollPos > prevScrollPos);
setPrevScrollPos(currentScrollPos);
}
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
const rootEl:HTMLDivElement = document.querySelector('#root')!;
const mainContainer:HTMLDivElement = document.querySelector('#appMainContainer')!;
2021-03-18 21:46:24 +03:30
// main container and root div need to change styles...
rootEl.style.display = 'flex';
mainContainer.style.display = 'none';
2021-03-18 21:46:24 +03:30
return () => {
rootEl.style.display = 'block';
mainContainer.style.display = 'block';
2021-03-23 04:28:23 +04:30
window.removeEventListener('scroll', handleScroll);
2021-03-18 21:46:24 +03:30
};
2021-03-19 14:52:20 +03:30
}, [handleScroll]);// handleScroll changes on every render
2021-03-18 21:46:24 +03:30
const handleClose = () => {
if (backTo.back) history.goBack();
else if (backTo.url) history.push(backTo.url);
else history.push(`/manga/${manga.id}`);
};
2021-03-18 21:46:24 +03:30
return (
<>
2021-05-15 23:22:37 +04:30
<Slide
direction="right"
in={drawerOpen}
timeout={200}
appear={false}
mountOnEnter
unmountOnExit
>
<Root sx={{
position: settings.staticNav ? 'sticky' : 'fixed',
}}
>
2021-05-15 23:22:37 +04:30
<header>
{!settings.staticNav
&& (
<IconButton
edge="start"
color="inherit"
aria-label="menu"
disableRipple
onClick={() => setDrawerOpen(false)}
size="large"
>
<KeyboardArrowLeftIcon />
</IconButton>
)}
<Typography variant="h1" textOverflow="ellipsis" overflow="hidden" sx={{ py: 1 }}>
{chapter.name}
</Typography>
<IconButton
edge="start"
color="inherit"
aria-label="menu"
disableRipple
onClick={handleClose}
2021-09-09 17:51:22 +04:30
size="large"
sx={{ mr: -1 }}
>
<CloseIcon />
</IconButton>
2021-05-15 23:22:37 +04:30
</header>
<ListItem
ContainerComponent="div"
sx={{
'& span': {
fontWeight: 'bold',
},
}}
>
2021-05-15 23:22:37 +04:30
<ListItemText primary="Reader Settings" />
<ListItemSecondaryAction>
2021-03-23 03:50:55 +04:30
<IconButton
edge="start"
color="inherit"
aria-label="menu"
disableRipple
2021-05-15 23:22:37 +04:30
disableFocusRipple
onClick={() => setSettingsCollapseOpen(!settingsCollapseOpen)}
2021-09-09 17:51:22 +04:30
size="large"
2021-03-23 03:50:55 +04:30
>
2021-05-15 23:22:37 +04:30
{settingsCollapseOpen && <KeyboardArrowUpIcon />}
{!settingsCollapseOpen && <KeyboardArrowDownIcon />}
2021-03-23 03:50:55 +04:30
</IconButton>
2021-05-15 23:22:37 +04:30
</ListItemSecondaryAction>
</ListItem>
<Collapse in={settingsCollapseOpen} timeout="auto" unmountOnExit>
<List>
<ListItem>
<ListItemText primary="Static Navigation" />
<ListItemSecondaryAction>
<Switch
edge="end"
checked={settings.staticNav}
onChange={(e) => setSettingValue('staticNav', e.target.checked)}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemText primary="Show page number" />
<ListItemSecondaryAction>
<Switch
edge="end"
checked={settings.showPageNumber}
onChange={(e) => setSettingValue('showPageNumber', e.target.checked)}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemText primary="Load next chapter at ending" />
<ListItemSecondaryAction>
<Switch
edge="end"
checked={settings.loadNextonEnding}
onChange={(e) => setSettingValue('loadNextonEnding', e.target.checked)}
/>
</ListItemSecondaryAction>
</ListItem>
2021-05-15 23:22:37 +04:30
<ListItem>
<ListItemText primary="Reader Type" />
<Select
variant="standard"
2021-05-15 23:22:37 +04:30
value={settings.readerType}
onChange={(e) => setSettingValue('readerType', e.target.value)}
sx={{ p: 0 }}
2021-03-23 04:28:23 +04:30
>
2021-05-25 13:12:42 +04:30
<MenuItem value="SingleLTR">
Single Page (LTR)
2021-05-25 13:12:42 +04:30
</MenuItem>
<MenuItem value="SingleRTL">
Single Page (RTL)
</MenuItem>
2021-05-25 13:12:42 +04:30
{/* <MenuItem value="SingleVertical">
Vertical(WIP)
</MenuItem> */}
<MenuItem value="DoubleLTR">
Double Page (LTR)
</MenuItem>
<MenuItem value="DoubleRTL">
Double Page (RTL)
</MenuItem>
2021-05-25 13:12:42 +04:30
<MenuItem value="Webtoon">
Webtoon
</MenuItem>
<MenuItem value="ContinuesVertical">
Continues Vertical
</MenuItem>
<MenuItem value="ContinuesHorizontalLTR">
Horizontal (LTR)
</MenuItem>
<MenuItem value="ContinuesHorizontalRTL">
Horizontal (RTL)
2021-05-28 11:57:31 -07:00
</MenuItem>
2021-05-15 23:22:37 +04:30
</Select>
</ListItem>
</List>
</Collapse>
<Divider sx={{ my: 1, mx: 2 }} />
<Navigation>
2021-05-15 23:22:37 +04:30
<span>
{`Currently on page ${curPage + 1} of ${chapter.pageCount}`}
2021-05-15 23:22:37 +04:30
</span>
<ChapterNavigation>
2021-05-15 23:22:37 +04:30
{chapter.index > 1
2021-09-09 17:51:22 +04:30
&& (
<Link
replace
to={{ pathname: `/manga/${manga.id}/chapter/${chapter.index - 1}`, state: history.location.state }}
2021-09-09 17:51:22 +04:30
>
<Button
variant="outlined"
sx={{ gridArea: 'prev' }}
2021-09-09 17:51:22 +04:30
startIcon={<KeyboardArrowLeftIcon />}
2021-03-23 03:50:55 +04:30
>
2021-09-09 17:51:22 +04:30
Prev. Chapter
</Button>
</Link>
)}
2021-05-15 23:22:37 +04:30
{chapter.index < chapter.chapterCount
2021-09-09 17:51:22 +04:30
&& (
<Link
replace
style={{ gridArea: 'next' }}
to={{ pathname: `/manga/${manga.id}/chapter/${chapter.index + 1}`, state: history.location.state }}
2021-09-09 17:51:22 +04:30
>
<Button
variant="outlined"
endIcon={<KeyboardArrowRightIcon />}
2021-03-23 03:50:55 +04:30
>
2021-09-09 17:51:22 +04:30
Next Chapter
</Button>
</Link>
)}
</ChapterNavigation>
</Navigation>
</Root>
2021-05-15 23:22:37 +04:30
</Slide>
2021-03-18 21:46:24 +03:30
<Zoom in={!drawerOpen}>
<Fade in={!hideOpenButton}>
<OpenDrawerButton
2021-03-18 21:46:24 +03:30
edge="start"
aria-label="menu"
disableRipple
disableFocusRipple
onClick={() => setDrawerOpen(true)}
2021-09-09 17:51:22 +04:30
size="large"
2021-03-18 21:46:24 +03:30
>
<KeyboardArrowRightIcon />
</OpenDrawerButton>
2021-03-18 21:46:24 +03:30
</Fade>
</Zoom>
</>
);
}