Add Resume Reading FAB Manga screen (#59)
* Added the Floating action button to Resume to the last read chapter - When a chapter is marked as read/unread the lastPageRead is changed to 1, Also fixed a bug which made the boolean expression appear in the ui Also removed some unused Styles Added the Resume/Start Button * changed a Resume button to a React compnent * Update src/screens/Manga.tsx Co-authored-by: Sascha Hahne <ntbm@users.noreply.github.com> * Update src/screens/Manga.tsx Co-authored-by: Sascha Hahne <ntbm@users.noreply.github.com> Co-authored-by: Sascha Hahne <ntbm@users.noreply.github.com>
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
@@ -19,43 +18,6 @@ import MenuItem from '@mui/material/MenuItem';
|
||||
import BookmarkIcon from '@mui/icons-material/Bookmark';
|
||||
import client from 'util/client';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
},
|
||||
bullet: {
|
||||
display: 'inline-block',
|
||||
margin: '0 2px',
|
||||
transform: 'scale(0.8)',
|
||||
},
|
||||
title: {
|
||||
fontSize: 14,
|
||||
},
|
||||
pos: {
|
||||
marginBottom: 12,
|
||||
},
|
||||
icon: {
|
||||
width: theme.spacing(7),
|
||||
height: theme.spacing(7),
|
||||
flex: '0 0 auto',
|
||||
marginRight: 16,
|
||||
},
|
||||
card: {
|
||||
margin: '10px',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: theme.palette.action.selected,
|
||||
transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
interface IProps{
|
||||
chapter: IChapter
|
||||
triggerChaptersUpdate: () => void
|
||||
@@ -63,7 +25,6 @@ interface IProps{
|
||||
}
|
||||
|
||||
export default function ChapterCard(props: IProps) {
|
||||
const classes = useStyles();
|
||||
const theme = useTheme();
|
||||
const { chapter, triggerChaptersUpdate, downloadStatusString } = props;
|
||||
|
||||
@@ -84,6 +45,7 @@ export default function ChapterCard(props: IProps) {
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append(key, value);
|
||||
if (key === 'read') { formData.append('lastPageRead', '1'); }
|
||||
client.patch(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`, formData)
|
||||
.then(() => triggerChaptersUpdate());
|
||||
};
|
||||
@@ -104,8 +66,25 @@ export default function ChapterCard(props: IProps) {
|
||||
return (
|
||||
<>
|
||||
<li>
|
||||
<Card className={classes.card}>
|
||||
<CardContent className={classes.root}>
|
||||
<Card sx={{
|
||||
margin: '10px',
|
||||
':hover': {
|
||||
backgroundColor: 'action.hover',
|
||||
transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
|
||||
},
|
||||
':active': {
|
||||
backgroundColor: 'action.selected',
|
||||
transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 2,
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
to={`/manga/${chapter.mangaId}/chapter/${chapter.index}`}
|
||||
style={{
|
||||
@@ -149,7 +128,7 @@ export default function ChapterCard(props: IProps) {
|
||||
{!chapter.bookmarked && 'Bookmark'}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => sendChange('read', !chapter.read)}>
|
||||
{`Mark as ${chapter.read && 'unread'} ${!chapter.read && 'read'}`}
|
||||
{`Mark as ${chapter.read ? 'unread' : 'read'}`}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => sendChange('markPrevRead', true)}>
|
||||
Mark previous as Read
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import React, { useEffect, useState, useContext } from 'react';
|
||||
import { Theme } from '@mui/material/styles';
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
import ChapterCard from 'components/ChapterCard';
|
||||
import MangaDetails from 'components/MangaDetails';
|
||||
@@ -16,6 +16,8 @@ import NavbarContext from 'components/context/NavbarContext';
|
||||
import client from 'util/client';
|
||||
import LoadingPlaceholder from 'components/util/LoadingPlaceholder';
|
||||
import makeToast from 'components/util/Toast';
|
||||
import { Fab } from '@mui/material';
|
||||
import PlayArrow from '@mui/icons-material/PlayArrow';
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
root: {
|
||||
@@ -62,6 +64,7 @@ export default function Manga() {
|
||||
const [chapterUpdateTriggerer, setChapterUpdateTriggerer] = useState(0);
|
||||
const [fetchedOnline, setFetchedOnline] = useState(false);
|
||||
const [fetchedOffline, setFetchedOffline] = useState(false);
|
||||
const [firstUnreadChapter, setFirstUnreadChapter] = useState<IChapter>();
|
||||
|
||||
const [, setWsClient] = useState<WebSocket>();
|
||||
const [{ queue }, setQueueState] = useState<IQueue>(initialQueue);
|
||||
@@ -129,6 +132,25 @@ export default function Manga() {
|
||||
});
|
||||
}, [fetchedOnline, fetchedOffline, chapterUpdateTriggerer]);
|
||||
|
||||
useEffect(() => {
|
||||
const a = [...chapters].reverse().find((chp) => !chp.read);
|
||||
setFirstUnreadChapter(a);
|
||||
}, [chapters]);
|
||||
|
||||
const ResumeFab = () => (firstUnreadChapter === undefined ? null
|
||||
: (
|
||||
<Fab
|
||||
sx={{ position: 'fixed', bottom: '5vw', right: '5vw' }}
|
||||
component={Link}
|
||||
variant="extended"
|
||||
color="primary"
|
||||
to={`/manga/${id}/chapter/${firstUnreadChapter.index}/page/${firstUnreadChapter.lastPageRead}`}
|
||||
>
|
||||
<PlayArrow />
|
||||
{firstUnreadChapter.index === 1 ? 'Start' : 'Resume' }
|
||||
</Fab>
|
||||
));
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<LoadingPlaceholder
|
||||
@@ -158,7 +180,7 @@ export default function Manga() {
|
||||
overscan={window.innerHeight * 0.5}
|
||||
/>
|
||||
</LoadingPlaceholder>
|
||||
|
||||
<ResumeFab />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
1
src/typings.d.ts
vendored
1
src/typings.d.ts
vendored
@@ -70,6 +70,7 @@ interface IChapter {
|
||||
read: boolean
|
||||
bookmarked: boolean
|
||||
lastPageRead: number
|
||||
lastReadAt: number
|
||||
index: number
|
||||
fetchedAt: number
|
||||
chapterCount: number
|
||||
|
||||
Reference in New Issue
Block a user