Added some key mappings to navigate pages (#95)

* Added some key mappings to navigate pages

* use keyboard event codes

* unused files removed

* use a reference to current page

* fix some bugs with Virtuoso

* add keymapping for space to navigate to next page

* commit my changes

* fix functions not regenerating

* fix partial scroll back to start of page issue

Co-authored-by: Aria Moradi <aria.moradi007@gmail.com>
This commit is contained in:
Manchewable 2021-05-24 12:16:05 -07:00 committed by GitHub
parent 16b34f874d
commit 23466cf853
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 33 deletions

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
* Copyright (C) Contributors to the Suwayomi project
*
@ -8,7 +7,6 @@
import { makeStyles } from '@material-ui/core/styles';
import React, { useEffect, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import Page from '../Page';
const useStyles = makeStyles({
@ -24,13 +22,12 @@ const useStyles = makeStyles({
export default function PagedReader(props: IReaderProps) {
const {
pages, settings, setCurPage, curPage, manga, chapter, nextChapter,
pages, settings, setCurPage, curPage, nextChapter,
} = props;
const classes = useStyles();
const history = useHistory();
const pageRef = useRef<HTMLDivElement>(null);
const selfRef = useRef<HTMLDivElement>(null);
function nextPage() {
if (curPage < pages.length - 1) {
@ -45,7 +42,11 @@ export default function PagedReader(props: IReaderProps) {
}
function keyboardControl(e:KeyboardEvent) {
switch (e.key) {
switch (e.code) {
case 'Space':
e.preventDefault();
nextPage();
break;
case 'ArrowRight':
nextPage();
break;
@ -66,17 +67,17 @@ export default function PagedReader(props: IReaderProps) {
}
useEffect(() => {
document.addEventListener('keyup', keyboardControl, false);
pageRef.current?.addEventListener('click', clickControl);
document.addEventListener('keydown', keyboardControl);
selfRef.current?.addEventListener('click', clickControl);
return () => {
document.removeEventListener('keyup', keyboardControl);
pageRef.current?.removeEventListener('click', clickControl);
document.removeEventListener('keydown', keyboardControl);
selfRef.current?.removeEventListener('click', clickControl);
};
}, [curPage, pageRef]);
}, [selfRef, curPage]);
return (
<div ref={pageRef} className={classes.reader}>
<div ref={selfRef} className={classes.reader}>
<Page
key={curPage}
index={curPage}

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
* Copyright (C) Contributors to the Suwayomi project
*
@ -7,8 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { makeStyles } from '@material-ui/core/styles';
import React, { useEffect, useRef, useState } from 'react';
import { useHistory } from 'react-router-dom';
import React, { useEffect, useRef } from 'react';
import Page from '../Page';
const useStyles = makeStyles({
@ -23,42 +21,91 @@ const useStyles = makeStyles({
export default function VerticalReader(props: IReaderProps) {
const {
pages, settings, setCurPage, curPage, manga, chapter, nextChapter,
pages, settings, setCurPage, curPage, chapter, nextChapter,
} = props;
const classes = useStyles();
const history = useHistory();
const [initialScroll, setInitialScroll] = useState(-1);
const initialPageRef = useRef<HTMLDivElement>(null);
const selfRef = useRef<HTMLDivElement>(null);
const pagesRef = useRef<HTMLDivElement[]>([]);
function nextPage() {
if (curPage < pages.length - 1) {
pagesRef.current[curPage + 1]?.scrollIntoView();
setCurPage((page) => page + 1);
} else if (settings.loadNextonEnding) {
nextChapter();
}
}
function prevPage() {
if (curPage > 0) {
const rect = pagesRef.current[curPage].getBoundingClientRect();
if (rect.y < 0 && rect.y + rect.height > 0) {
pagesRef.current[curPage]?.scrollIntoView();
} else {
pagesRef.current[curPage - 1]?.scrollIntoView();
setCurPage(curPage - 1);
}
}
}
function keyboardControl(e:KeyboardEvent) {
switch (e.code) {
case 'Space':
e.preventDefault();
nextPage();
break;
case 'ArrowRight':
nextPage();
break;
case 'ArrowLeft':
prevPage();
break;
default:
break;
}
}
function clickControl(e:MouseEvent) {
if (e.clientX > window.innerWidth / 2) {
nextPage();
} else {
prevPage();
}
}
const handleLoadNextonEnding = () => {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
nextChapter();
}
};
useEffect(() => {
if (settings.loadNextonEnding) { window.addEventListener('scroll', handleLoadNextonEnding); }
document.addEventListener('keydown', keyboardControl, false);
selfRef.current?.addEventListener('click', clickControl);
return () => {
window.removeEventListener('scroll', handleLoadNextonEnding);
document.removeEventListener('scroll', handleLoadNextonEnding);
document.removeEventListener('keydown', keyboardControl);
selfRef.current?.removeEventListener('click', clickControl);
};
}, []);
}, [selfRef, curPage]);
useEffect(() => {
if ((chapter as IChapter).lastPageRead > -1) {
setInitialScroll((chapter as IChapter).lastPageRead);
// scroll last read page into view
let initialPage = (chapter as IChapter).lastPageRead;
if (initialPage > pages.length - 1) {
initialPage = pages.length - 1;
}
if (initialPage > -1) {
pagesRef.current[initialPage].scrollIntoView();
}
}, []);
useEffect(() => {
if (initialScroll > -1) {
initialPageRef.current?.scrollIntoView();
}
}, [initialScroll, initialPageRef.current]);
return (
<div className={classes.reader}>
<div ref={selfRef} className={classes.reader}>
{
pages.map((page) => (
<Page
@ -67,7 +114,7 @@ export default function VerticalReader(props: IReaderProps) {
src={page.src}
setCurPage={setCurPage}
settings={settings}
ref={page.index === initialScroll ? initialPageRef : null}
ref={(e:HTMLDivElement) => { pagesRef.current[page.index] = e; }}
/>
))
}

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
* Copyright (C) Contributors to the Suwayomi project
*
@ -11,7 +10,6 @@ import { makeStyles } from '@material-ui/core/styles';
import React, { useContext, useEffect, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import HorizontalPager from '../components/reader/pager/HorizontalPager';
import Page from '../components/reader/Page';
import PageNumber from '../components/reader/PageNumber';
import WebtoonPager from '../components/reader/pager/PagedPager';
import VerticalPager from '../components/reader/pager/VerticalPager';
@ -72,6 +70,7 @@ export default function Reader() {
const [chapter, setChapter] = useState<IChapter | IPartialChpter>(initialChapter());
const [curPage, setCurPage] = useState<number>(0);
const { setOverride, setTitle } = useContext(NavbarContext);
useEffect(() => {
// make sure settings has all the keys
const settingsClone = cloneObject(settings) as any;