* Correctly scroll to page Using "curPage" as the "initialPage" broke "scrolling up". The page got reset to the first page in that case * Support resume and scrolling to page for "DoublePagedPager" * Support resume and scrolling to page for "PagedPager" * Prevent "ReaderNavBar" from disappearing in "VerticalPager" Due to handling the overflow on the "root" div and the "nav bar" being sticky and having a combined with of 100vw with the "vertical pager", once the first page was reached, that was behind the 100vw, the "nav bar" got moved out of the screen. This made using the "nav bar" unusable for the "vertical pager".
113 lines
3.0 KiB
TypeScript
113 lines
3.0 KiB
TypeScript
/*
|
|
* 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 React, { useEffect, useRef } from 'react';
|
|
import { Box } from '@mui/system';
|
|
import Page from 'components/reader/Page';
|
|
|
|
export default function PagedReader(props: IReaderProps) {
|
|
const { pages, settings, setCurPage, initialPage, curPage, nextChapter, prevChapter } = props;
|
|
|
|
const selfRef = useRef<HTMLDivElement>(null);
|
|
|
|
const changePage = (newPage: number) => {
|
|
setCurPage(newPage);
|
|
window.scroll({ top: 0 });
|
|
};
|
|
|
|
function nextPage() {
|
|
if (curPage < pages.length - 1) {
|
|
changePage(curPage + 1);
|
|
} else if (settings.loadNextOnEnding) {
|
|
nextChapter();
|
|
}
|
|
}
|
|
|
|
function prevPage() {
|
|
if (curPage > 0) {
|
|
changePage(curPage - 1);
|
|
} else {
|
|
prevChapter();
|
|
}
|
|
}
|
|
|
|
function goLeft() {
|
|
if (settings.readerType === 'SingleLTR') {
|
|
prevPage();
|
|
} else if (settings.readerType === 'SingleRTL') {
|
|
nextPage();
|
|
}
|
|
}
|
|
|
|
function goRight() {
|
|
if (settings.readerType === 'SingleLTR') {
|
|
nextPage();
|
|
} else if (settings.readerType === 'SingleRTL') {
|
|
prevPage();
|
|
}
|
|
}
|
|
|
|
function keyboardControl(e: KeyboardEvent) {
|
|
switch (e.code) {
|
|
case 'Space':
|
|
e.preventDefault();
|
|
nextPage();
|
|
break;
|
|
case 'ArrowRight':
|
|
goRight();
|
|
break;
|
|
case 'ArrowLeft':
|
|
goLeft();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
function clickControl(e: MouseEvent) {
|
|
if (e.clientX > window.innerWidth / 2) {
|
|
goRight();
|
|
} else {
|
|
goLeft();
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
document.addEventListener('keydown', keyboardControl);
|
|
selfRef.current?.addEventListener('click', clickControl);
|
|
|
|
return () => {
|
|
document.removeEventListener('keydown', keyboardControl);
|
|
selfRef.current?.removeEventListener('click', clickControl);
|
|
};
|
|
}, [selfRef, curPage, settings.readerType]);
|
|
|
|
useEffect(() => {
|
|
// Delay scrolling to next cycle
|
|
setTimeout(() => {
|
|
// scroll last read page into view when initialPage changes
|
|
changePage(initialPage);
|
|
}, 0);
|
|
}, [initialPage]);
|
|
|
|
return (
|
|
<Box
|
|
ref={selfRef}
|
|
sx={{
|
|
display: 'flex',
|
|
flexDirection: 'row',
|
|
justifyContent: 'center',
|
|
margin: '0 auto',
|
|
width: '100%',
|
|
height: '100vh',
|
|
}}
|
|
>
|
|
<Page key={curPage} index={curPage} onImageLoad={() => {}} src={pages[curPage].src} settings={settings} />
|
|
</Box>
|
|
);
|
|
}
|