Add infinite scroll to reader
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { memo, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDefaultReaderSettings } from '@/modules/reader/services/ReaderSettingsMetadata.ts';
|
||||
@@ -33,7 +33,7 @@ import { ReaderHotkeys } from '@/modules/reader/components/ReaderHotkeys.tsx';
|
||||
import {
|
||||
IReaderSettings,
|
||||
IReaderSettingsWithDefaultFlag,
|
||||
ReaderResumeMode,
|
||||
ReaderOpenChapterLocationState,
|
||||
ReaderStateChapters,
|
||||
TReaderAutoScrollContext,
|
||||
TReaderStateMangaContext,
|
||||
@@ -49,7 +49,6 @@ import { useReaderAutoScrollContext } from '@/modules/reader/contexts/ReaderAuto
|
||||
import { TReaderTapZoneContext } from '@/modules/reader/types/TapZoneLayout.types.ts';
|
||||
import { useReaderTapZoneContext } from '@/modules/reader/contexts/ReaderTapZoneContext.tsx';
|
||||
import { useReaderResetStates } from '@/modules/reader/hooks/useReaderResetStates.ts';
|
||||
import { useReaderSetPagesState } from '@/modules/reader/hooks/useReaderSetPagesState.ts';
|
||||
import { useReaderSetSettingsState } from '@/modules/reader/hooks/useReaderSetSettingsState.ts';
|
||||
import { useReaderShowSettingPreviewOnChange } from '@/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts';
|
||||
import { useReaderSetChaptersState } from '@/modules/reader/hooks/useReaderSetChaptersState.ts';
|
||||
@@ -70,9 +69,9 @@ const BaseReader = ({
|
||||
shouldShowReadingModePreview,
|
||||
shouldShowTapZoneLayoutPreview,
|
||||
setSettings,
|
||||
initialChapter,
|
||||
chapterForDuplicatesHandling,
|
||||
currentChapter,
|
||||
mangaChapters,
|
||||
setReaderStateChapters,
|
||||
firstPageUrl,
|
||||
totalPages,
|
||||
@@ -94,7 +93,10 @@ const BaseReader = ({
|
||||
'shouldSkipDupChapters' | 'backgroundColor' | 'shouldShowReadingModePreview' | 'shouldShowTapZoneLayoutPreview'
|
||||
> &
|
||||
Pick<IReaderSettingsWithDefaultFlag, 'readingMode' | 'tapZoneLayout' | 'tapZoneInvertMode'> &
|
||||
Pick<ReaderStateChapters, 'chapterForDuplicatesHandling' | 'currentChapter' | 'mangaChapters' | 'setReaderStateChapters'> &
|
||||
Pick<
|
||||
ReaderStateChapters,
|
||||
'initialChapter' | 'chapterForDuplicatesHandling' | 'currentChapter' | 'setReaderStateChapters'
|
||||
> &
|
||||
Pick<
|
||||
ReaderStatePages,
|
||||
| 'totalPages'
|
||||
@@ -111,9 +113,7 @@ const BaseReader = ({
|
||||
cancelAutoScroll: TReaderAutoScrollContext['cancel'];
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { resumeMode } = useLocation<{
|
||||
resumeMode: ReaderResumeMode;
|
||||
}>().state ?? { resumeMode: ReaderResumeMode.START };
|
||||
const { updateInitialChapter } = useLocation<ReaderOpenChapterLocationState>().state ?? {};
|
||||
|
||||
const scrollElementRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
@@ -128,20 +128,6 @@ const BaseReader = ({
|
||||
|
||||
const mangaResponse = requestManager.useGetManga<GetMangaReaderQuery>(GET_MANGA_READER, mangaId);
|
||||
const chaptersResponse = requestManager.useGetMangaChapters<GetChaptersReaderQuery>(GET_CHAPTERS_READER, mangaId);
|
||||
const [arePagesFetched, setArePagesFetched] = useState(false);
|
||||
const [fetchPages, pagesResponse] = requestManager.useGetChapterPagesFetch(-1);
|
||||
|
||||
const doFetchPages = useCallback(() => {
|
||||
if (!currentChapter) {
|
||||
return;
|
||||
}
|
||||
|
||||
setArePagesFetched(false);
|
||||
|
||||
fetchPages({ variables: { input: { chapterId: currentChapter.id } } }).catch(
|
||||
defaultPromiseErrorHandler('Reader::fetchPages'),
|
||||
);
|
||||
}, [fetchPages, currentChapter?.id]);
|
||||
|
||||
const {
|
||||
metadata: defaultSettingsMetadata,
|
||||
@@ -149,21 +135,13 @@ const BaseReader = ({
|
||||
request: defaultSettingsResponse,
|
||||
} = useDefaultReaderSettings();
|
||||
|
||||
const doesChapterExist =
|
||||
!chaptersResponse.loading &&
|
||||
!chaptersResponse.error &&
|
||||
chapterSourceOrder >= 0 &&
|
||||
chapterSourceOrder <= mangaChapters.length;
|
||||
|
||||
const isLoading =
|
||||
currentChapter === undefined ||
|
||||
!areSettingsSet ||
|
||||
mangaResponse.loading ||
|
||||
chaptersResponse.loading ||
|
||||
defaultSettingsResponse.loading ||
|
||||
pagesResponse.loading ||
|
||||
(doesChapterExist && !arePagesFetched && !chaptersResponse.error && !pagesResponse.error);
|
||||
const error = mangaResponse.error ?? chaptersResponse.error ?? defaultSettingsResponse.error ?? pagesResponse.error;
|
||||
defaultSettingsResponse.loading;
|
||||
const error = mangaResponse.error ?? chaptersResponse.error ?? defaultSettingsResponse.error;
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!manga || !currentChapter) {
|
||||
@@ -174,11 +152,6 @@ const BaseReader = ({
|
||||
setTitle(`${manga.title}: ${currentChapter.name}`);
|
||||
}, [t, mangaId, chapterSourceOrder, manga, currentChapter]);
|
||||
|
||||
useEffect(() => {
|
||||
doFetchPages();
|
||||
return () => setArePagesFetched(false);
|
||||
}, [currentChapter?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
setManga(mangaResponse.data?.manga);
|
||||
}, [mangaResponse.data?.manga]);
|
||||
@@ -197,19 +170,6 @@ const BaseReader = ({
|
||||
setSettings,
|
||||
cancelAutoScroll,
|
||||
);
|
||||
useReaderSetPagesState(
|
||||
pagesResponse,
|
||||
resumeMode,
|
||||
currentChapter,
|
||||
setArePagesFetched,
|
||||
setTotalPages,
|
||||
setPages,
|
||||
setPageUrls,
|
||||
setPageLoadStates,
|
||||
setCurrentPageIndex,
|
||||
setPageToScrollToIndex,
|
||||
setTransitionPageMode,
|
||||
);
|
||||
useReaderSetSettingsState(
|
||||
mangaResponse,
|
||||
defaultSettingsResponse,
|
||||
@@ -232,6 +192,7 @@ const BaseReader = ({
|
||||
useReaderSetChaptersState(
|
||||
chaptersResponse,
|
||||
chapterSourceOrder,
|
||||
updateInitialChapter ? undefined : initialChapter,
|
||||
chapterForDuplicatesHandling,
|
||||
setReaderStateChapters,
|
||||
shouldSkipDupChapters,
|
||||
@@ -283,10 +244,6 @@ const BaseReader = ({
|
||||
if (chaptersResponse.error) {
|
||||
chaptersResponse.refetch().catch(defaultPromiseErrorHandler('Reader::refetchChapters'));
|
||||
}
|
||||
|
||||
if (pagesResponse.error) {
|
||||
doFetchPages();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -311,10 +268,6 @@ const BaseReader = ({
|
||||
return <EmptyViewAbsoluteCentered message={t('reader.error.label.chapter_not_found')} />;
|
||||
}
|
||||
|
||||
if (currentChapter && !currentChapter?.pageCount) {
|
||||
return <EmptyViewAbsoluteCentered message={t('reader.error.label.no_pages_found')} retry={doFetchPages} />;
|
||||
}
|
||||
|
||||
if (!manga || !currentChapter) {
|
||||
return null;
|
||||
}
|
||||
@@ -395,9 +348,9 @@ export const Reader = withPropsFrom(
|
||||
'shouldShowReadingModePreview',
|
||||
'shouldShowTapZoneLayoutPreview',
|
||||
'setSettings',
|
||||
'initialChapter',
|
||||
'chapterForDuplicatesHandling',
|
||||
'currentChapter',
|
||||
'mangaChapters',
|
||||
'setReaderStateChapters',
|
||||
'firstPageUrl',
|
||||
'totalPages',
|
||||
|
||||
Reference in New Issue
Block a user