From beda5096d18bc13e56da4fd91355298244307f80 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sat, 26 Apr 2025 23:19:01 +0200 Subject: [PATCH] Add option to disable "infinite chapter scroll" --- public/locales/en.json | 4 +++ src/modules/metadata/Metadata.constants.ts | 1 + .../behaviour/ReaderBehaviourSettings.tsx | 12 ++++++++ .../components/viewer/ReaderChapterViewer.tsx | 9 +++++- .../ReaderInfiniteScrollUpdateChapter.tsx | 30 ++++++++++--------- .../reader/components/viewer/ReaderViewer.tsx | 4 +++ .../constants/ReaderSettings.constants.tsx | 2 ++ .../useReaderInfiniteScrollUpdateChapter.ts | 8 ++++- src/modules/reader/services/ReaderControls.ts | 16 +++++++--- src/modules/reader/types/Reader.types.ts | 1 + 10 files changed, 67 insertions(+), 20 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index 69761542..3eb013c6 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -946,6 +946,10 @@ "stretch_image": "Toggle stretch image" }, "image_preload_amount": "Preload images", + "infinite_scroll": { + "description": "Keep previous and upcoming chapters visible while reading in continuous reading modes, allowing seamless scrolling between chapters.", + "title": "Continuous chapter display" + }, "label": { "behaviour": "Behaviour", "fit_page_to_window": "Fit page to window", diff --git a/src/modules/metadata/Metadata.constants.ts b/src/modules/metadata/Metadata.constants.ts index 44025a08..d70097e2 100644 --- a/src/modules/metadata/Metadata.constants.ts +++ b/src/modules/metadata/Metadata.constants.ts @@ -87,6 +87,7 @@ const APP_METADATA_OBJECT: Record = { showChapterNumber: undefined, extensionLanguages: undefined, showNsfw: undefined, + shouldUseInfiniteScroll: undefined, }; export const VALID_APP_METADATA_KEYS = Object.keys(APP_METADATA_OBJECT); diff --git a/src/modules/reader/components/settings/behaviour/ReaderBehaviourSettings.tsx b/src/modules/reader/components/settings/behaviour/ReaderBehaviourSettings.tsx index 360f8198..7b9b5803 100644 --- a/src/modules/reader/components/settings/behaviour/ReaderBehaviourSettings.tsx +++ b/src/modules/reader/components/settings/behaviour/ReaderBehaviourSettings.tsx @@ -54,6 +54,18 @@ export const ReaderBehaviourSettings = ({ onChange={(_, checked) => updateSetting('shouldOffsetDoubleSpreads', checked)} /> )} + + {t('reader.settings.infinite_scroll.title')} + + {t('reader.settings.infinite_scroll.description')} + + + } + checked={settings.shouldUseInfiniteScroll} + onChange={(_, checked) => updateSetting('shouldUseInfiniteScroll', checked)} + /> diff --git a/src/modules/reader/components/viewer/ReaderChapterViewer.tsx b/src/modules/reader/components/viewer/ReaderChapterViewer.tsx index 052ad8bf..e7d9287c 100644 --- a/src/modules/reader/components/viewer/ReaderChapterViewer.tsx +++ b/src/modules/reader/components/viewer/ReaderChapterViewer.tsx @@ -64,6 +64,7 @@ const BaseReaderChapterViewer = ({ pageScaleMode, shouldOffsetDoubleSpreads, readingDirection, + shouldUseInfiniteScroll, imagePreLoadAmount, pageGap, chapterId, @@ -107,7 +108,12 @@ const BaseReaderChapterViewer = ({ Omit & Pick< IReaderSettings, - 'readingMode' | 'shouldOffsetDoubleSpreads' | 'readingDirection' | 'readerWidth' | 'pageScaleMode' + | 'readingMode' + | 'shouldOffsetDoubleSpreads' + | 'readingDirection' + | 'readerWidth' + | 'pageScaleMode' + | 'shouldUseInfiniteScroll' > & Pick & { updateCurrentPageIndex: ReturnType; @@ -412,6 +418,7 @@ const BaseReaderChapterViewer = ({ & { - readingMode: ReadingMode; - readingDirection: ReadingDirection; - chapterId: ChapterIdInfo['id']; - previousChapterId?: ChapterIdInfo['id']; - nextChapterId?: ChapterIdInfo['id']; - isPreviousChapterVisible: boolean; - isCurrentChapter: boolean; - isNextChapterVisible: boolean; - imageWrapper: HTMLElement | null; - openChapter: ReturnType; - scrollElement: HTMLElement | null; -}) => { +}: Pick & + Pick & { + chapterId: ChapterIdInfo['id']; + previousChapterId?: ChapterIdInfo['id']; + nextChapterId?: ChapterIdInfo['id']; + isPreviousChapterVisible: boolean; + isCurrentChapter: boolean; + isNextChapterVisible: boolean; + imageWrapper: HTMLElement | null; + openChapter: ReturnType; + scrollElement: HTMLElement | null; + }) => { useReaderInfiniteScrollUpdateChapter( 'first', chapterId, @@ -48,6 +48,7 @@ const BaseReaderInfiniteScrollUpdateChapter = ({ isPreviousChapterVisible, readingMode, readingDirection, + shouldUseInfiniteScroll, openChapter, imageWrapper, scrollbarXSize, @@ -62,6 +63,7 @@ const BaseReaderInfiniteScrollUpdateChapter = ({ isNextChapterVisible, readingMode, readingDirection, + shouldUseInfiniteScroll, openChapter, imageWrapper, scrollbarXSize, diff --git a/src/modules/reader/components/viewer/ReaderViewer.tsx b/src/modules/reader/components/viewer/ReaderViewer.tsx index bdb091b5..8f636fb2 100644 --- a/src/modules/reader/components/viewer/ReaderViewer.tsx +++ b/src/modules/reader/components/viewer/ReaderViewer.tsx @@ -94,6 +94,7 @@ const BaseReaderViewer = forwardRef( setTransitionPageMode, readingMode, readingDirection, + shouldUseInfiniteScroll, readerWidth, pageScaleMode, shouldOffsetDoubleSpreads, @@ -134,6 +135,7 @@ const BaseReaderViewer = forwardRef( IReaderSettings, | 'readingMode' | 'readingDirection' + | 'shouldUseInfiniteScroll' | 'readerWidth' | 'pageScaleMode' | 'shouldOffsetDoubleSpreads' @@ -408,6 +410,7 @@ const BaseReaderViewer = forwardRef( pageScaleMode={pageScaleMode} shouldOffsetDoubleSpreads={shouldOffsetDoubleSpreads} readingDirection={readingDirection} + shouldUseInfiniteScroll={shouldUseInfiniteScroll} updateCurrentPageIndex={isCurrentChapter ? updateCurrentPageIndex : noOp} scrollIntoView={isCurrentChapter && visibleChapters.scrollIntoView} resumeMode={getReaderChapterViewResumeMode( @@ -465,6 +468,7 @@ export const ReaderViewer = withPropsFrom( 'setTransitionPageMode', 'readingMode', 'readingDirection', + 'shouldUseInfiniteScroll', 'readerWidth', 'pageScaleMode', 'shouldOffsetDoubleSpreads', diff --git a/src/modules/reader/constants/ReaderSettings.constants.tsx b/src/modules/reader/constants/ReaderSettings.constants.tsx index 0d7de605..6db9d723 100644 --- a/src/modules/reader/constants/ReaderSettings.constants.tsx +++ b/src/modules/reader/constants/ReaderSettings.constants.tsx @@ -71,6 +71,7 @@ const GLOBAL_READER_SETTING_OBJECT: Record = { diff --git a/src/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts b/src/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts index bca9588e..cc869b75 100644 --- a/src/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts +++ b/src/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts @@ -240,6 +240,7 @@ export const useReaderInfiniteScrollUpdateChapter = ( isChapterToOpenVisible: boolean, readingMode: ReadingMode, readingDirection: ReadingDirection, + shouldUseInfiniteScroll: boolean, openChapter: ReturnType, image: HTMLElement | null, scrollbarXSize: number, @@ -250,7 +251,11 @@ export const useReaderInfiniteScrollUpdateChapter = ( image, useCallback( (entries) => { - if (!isContinuousReadingMode(readingMode) || chapterToOpenId === undefined) { + if ( + !shouldUseInfiniteScroll || + !isContinuousReadingMode(readingMode) || + chapterToOpenId === undefined + ) { return; } @@ -297,6 +302,7 @@ export const useReaderInfiniteScrollUpdateChapter = ( isChapterToOpenVisible, readingMode, readingDirection, + shouldUseInfiniteScroll, openChapter, scrollbarXSize, scrollbarYSize, diff --git a/src/modules/reader/services/ReaderControls.ts b/src/modules/reader/services/ReaderControls.ts index 17f37bc9..47db755f 100644 --- a/src/modules/reader/services/ReaderControls.ts +++ b/src/modules/reader/services/ReaderControls.ts @@ -175,8 +175,12 @@ export class ReaderControls { scrollIntoView?: boolean, ) => void { const { t } = useTranslation(); - const { readingMode, shouldInformAboutMissingChapter, shouldInformAboutScanlatorChange } = - ReaderService.useSettings(); + const { + readingMode, + shouldInformAboutMissingChapter, + shouldInformAboutScanlatorChange, + shouldUseInfiniteScroll, + } = ReaderService.useSettings(); const { currentChapter, previousChapter, @@ -239,7 +243,7 @@ export class ReaderControls { const isAlreadyLoaded = lastLeadingChapterSourceOrder <= chapterToOpen.sourceOrder && lastTrailingChapterSourceOrder >= chapterToOpen.sourceOrder; - const keepRenderedChapters = !scrollIntoView || isAlreadyLoaded; + const keepRenderedChapters = shouldUseInfiniteScroll && (!scrollIntoView || isAlreadyLoaded); if (keepRenderedChapters) { setReaderStateChapters((prevState) => @@ -255,7 +259,10 @@ export class ReaderControls { } openChapter(chapterToOpen, { - resumeMode: getReaderOpenChapterResumeMode(isSpecificChapterMode, isPreviousChapter), + resumeMode: getReaderOpenChapterResumeMode( + isSpecificChapterMode || !keepRenderedChapters, + isPreviousChapter, + ), updateInitialChapter: !keepRenderedChapters, }); } catch (error) { @@ -274,6 +281,7 @@ export class ReaderControls { shouldInformAboutScanlatorChange, lastLeadingChapterSourceOrder, lastTrailingChapterSourceOrder, + shouldUseInfiniteScroll, ], ); } diff --git a/src/modules/reader/types/Reader.types.ts b/src/modules/reader/types/Reader.types.ts index 6fe7227e..6ffd281a 100644 --- a/src/modules/reader/types/Reader.types.ts +++ b/src/modules/reader/types/Reader.types.ts @@ -160,6 +160,7 @@ export interface IReaderSettingsGlobal { shouldInformAboutMissingChapter: boolean; shouldInformAboutScanlatorChange: boolean; scrollAmount: ReaderScrollAmount; + shouldUseInfiniteScroll: boolean; } export interface IReaderSettingsManga {