Add option to disable "infinite chapter scroll"
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -87,6 +87,7 @@ const APP_METADATA_OBJECT: Record<AppMetadataKeys, undefined> = {
|
||||
showChapterNumber: undefined,
|
||||
extensionLanguages: undefined,
|
||||
showNsfw: undefined,
|
||||
shouldUseInfiniteScroll: undefined,
|
||||
};
|
||||
|
||||
export const VALID_APP_METADATA_KEYS = Object.keys(APP_METADATA_OBJECT);
|
||||
|
||||
@@ -54,6 +54,18 @@ export const ReaderBehaviourSettings = ({
|
||||
onChange={(_, checked) => updateSetting('shouldOffsetDoubleSpreads', checked)}
|
||||
/>
|
||||
)}
|
||||
<CheckboxInput
|
||||
label={
|
||||
<Box>
|
||||
<Typography>{t('reader.settings.infinite_scroll.title')}</Typography>
|
||||
<Typography variant="body2" color="textDisabled">
|
||||
{t('reader.settings.infinite_scroll.description')}
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
checked={settings.shouldUseInfiniteScroll}
|
||||
onChange={(_, checked) => updateSetting('shouldUseInfiniteScroll', checked)}
|
||||
/>
|
||||
<CheckboxInput
|
||||
label={
|
||||
<Box>
|
||||
|
||||
@@ -64,6 +64,7 @@ const BaseReaderChapterViewer = ({
|
||||
pageScaleMode,
|
||||
shouldOffsetDoubleSpreads,
|
||||
readingDirection,
|
||||
shouldUseInfiniteScroll,
|
||||
imagePreLoadAmount,
|
||||
pageGap,
|
||||
chapterId,
|
||||
@@ -107,7 +108,12 @@ const BaseReaderChapterViewer = ({
|
||||
Omit<ReaderPagerProps, 'pages' | 'totalPages' | 'pageLoadStates' | 'handleAsInitialRender' | 'resumeMode'> &
|
||||
Pick<
|
||||
IReaderSettings,
|
||||
'readingMode' | 'shouldOffsetDoubleSpreads' | 'readingDirection' | 'readerWidth' | 'pageScaleMode'
|
||||
| 'readingMode'
|
||||
| 'shouldOffsetDoubleSpreads'
|
||||
| 'readingDirection'
|
||||
| 'readerWidth'
|
||||
| 'pageScaleMode'
|
||||
| 'shouldUseInfiniteScroll'
|
||||
> &
|
||||
Pick<ReaderStateChapters, 'setReaderStateChapters'> & {
|
||||
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
||||
@@ -412,6 +418,7 @@ const BaseReaderChapterViewer = ({
|
||||
<ReaderInfiniteScrollUpdateChapter
|
||||
readingMode={readingMode}
|
||||
readingDirection={readingDirection}
|
||||
shouldUseInfiniteScroll={shouldUseInfiniteScroll}
|
||||
chapterId={chapterId}
|
||||
previousChapterId={previousChapterId}
|
||||
nextChapterId={nextChapterId}
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
import { memo } from 'react';
|
||||
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
|
||||
import { useReaderInfiniteScrollUpdateChapter } from '@/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts';
|
||||
import { ReadingDirection, ReadingMode, TReaderScrollbarContext } from '@/modules/reader/types/Reader.types.ts';
|
||||
import { IReaderSettings, TReaderScrollbarContext } from '@/modules/reader/types/Reader.types.ts';
|
||||
import { ReaderControls } from '@/modules/reader/services/ReaderControls.ts';
|
||||
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||
|
||||
const BaseReaderInfiniteScrollUpdateChapter = ({
|
||||
readingMode,
|
||||
readingDirection,
|
||||
shouldUseInfiniteScroll,
|
||||
chapterId,
|
||||
previousChapterId,
|
||||
nextChapterId,
|
||||
@@ -27,19 +28,18 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
|
||||
scrollbarXSize,
|
||||
scrollbarYSize,
|
||||
scrollElement,
|
||||
}: Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'> & {
|
||||
readingMode: ReadingMode;
|
||||
readingDirection: ReadingDirection;
|
||||
chapterId: ChapterIdInfo['id'];
|
||||
previousChapterId?: ChapterIdInfo['id'];
|
||||
nextChapterId?: ChapterIdInfo['id'];
|
||||
isPreviousChapterVisible: boolean;
|
||||
isCurrentChapter: boolean;
|
||||
isNextChapterVisible: boolean;
|
||||
imageWrapper: HTMLElement | null;
|
||||
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>;
|
||||
scrollElement: HTMLElement | null;
|
||||
}) => {
|
||||
}: Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'> &
|
||||
Pick<IReaderSettings, 'readingMode' | 'readingDirection' | 'shouldUseInfiniteScroll'> & {
|
||||
chapterId: ChapterIdInfo['id'];
|
||||
previousChapterId?: ChapterIdInfo['id'];
|
||||
nextChapterId?: ChapterIdInfo['id'];
|
||||
isPreviousChapterVisible: boolean;
|
||||
isCurrentChapter: boolean;
|
||||
isNextChapterVisible: boolean;
|
||||
imageWrapper: HTMLElement | null;
|
||||
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>;
|
||||
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,
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -71,6 +71,7 @@ const GLOBAL_READER_SETTING_OBJECT: Record<keyof IReaderSettingsGlobal, undefine
|
||||
shouldInformAboutMissingChapter: undefined,
|
||||
shouldInformAboutScanlatorChange: undefined,
|
||||
scrollAmount: undefined,
|
||||
shouldUseInfiniteScroll: undefined,
|
||||
};
|
||||
|
||||
export const GLOBAL_READER_SETTING_KEYS = Object.keys(GLOBAL_READER_SETTING_OBJECT);
|
||||
@@ -155,6 +156,7 @@ export const DEFAULT_READER_SETTINGS: IReaderSettings = {
|
||||
shouldInformAboutMissingChapter: true,
|
||||
shouldInformAboutScanlatorChange: true,
|
||||
scrollAmount: ReaderScrollAmount.LARGE,
|
||||
shouldUseInfiniteScroll: true,
|
||||
};
|
||||
|
||||
export const READER_PROGRESS_BAR_POSITION_TO_PLACEMENT: Record<ProgressBarPosition, TooltipProps['placement']> = {
|
||||
|
||||
@@ -240,6 +240,7 @@ export const useReaderInfiniteScrollUpdateChapter = (
|
||||
isChapterToOpenVisible: boolean,
|
||||
readingMode: ReadingMode,
|
||||
readingDirection: ReadingDirection,
|
||||
shouldUseInfiniteScroll: boolean,
|
||||
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>,
|
||||
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,
|
||||
|
||||
@@ -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,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ export interface IReaderSettingsGlobal {
|
||||
shouldInformAboutMissingChapter: boolean;
|
||||
shouldInformAboutScanlatorChange: boolean;
|
||||
scrollAmount: ReaderScrollAmount;
|
||||
shouldUseInfiniteScroll: boolean;
|
||||
}
|
||||
|
||||
export interface IReaderSettingsManga {
|
||||
|
||||
Reference in New Issue
Block a user