Add option to disable "infinite chapter scroll"
This commit is contained in:
@@ -946,6 +946,10 @@
|
|||||||
"stretch_image": "Toggle stretch image"
|
"stretch_image": "Toggle stretch image"
|
||||||
},
|
},
|
||||||
"image_preload_amount": "Preload images",
|
"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": {
|
"label": {
|
||||||
"behaviour": "Behaviour",
|
"behaviour": "Behaviour",
|
||||||
"fit_page_to_window": "Fit page to window",
|
"fit_page_to_window": "Fit page to window",
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ const APP_METADATA_OBJECT: Record<AppMetadataKeys, undefined> = {
|
|||||||
showChapterNumber: undefined,
|
showChapterNumber: undefined,
|
||||||
extensionLanguages: undefined,
|
extensionLanguages: undefined,
|
||||||
showNsfw: undefined,
|
showNsfw: undefined,
|
||||||
|
shouldUseInfiniteScroll: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VALID_APP_METADATA_KEYS = Object.keys(APP_METADATA_OBJECT);
|
export const VALID_APP_METADATA_KEYS = Object.keys(APP_METADATA_OBJECT);
|
||||||
|
|||||||
@@ -54,6 +54,18 @@ export const ReaderBehaviourSettings = ({
|
|||||||
onChange={(_, checked) => updateSetting('shouldOffsetDoubleSpreads', checked)}
|
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
|
<CheckboxInput
|
||||||
label={
|
label={
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ const BaseReaderChapterViewer = ({
|
|||||||
pageScaleMode,
|
pageScaleMode,
|
||||||
shouldOffsetDoubleSpreads,
|
shouldOffsetDoubleSpreads,
|
||||||
readingDirection,
|
readingDirection,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
imagePreLoadAmount,
|
imagePreLoadAmount,
|
||||||
pageGap,
|
pageGap,
|
||||||
chapterId,
|
chapterId,
|
||||||
@@ -107,7 +108,12 @@ const BaseReaderChapterViewer = ({
|
|||||||
Omit<ReaderPagerProps, 'pages' | 'totalPages' | 'pageLoadStates' | 'handleAsInitialRender' | 'resumeMode'> &
|
Omit<ReaderPagerProps, 'pages' | 'totalPages' | 'pageLoadStates' | 'handleAsInitialRender' | 'resumeMode'> &
|
||||||
Pick<
|
Pick<
|
||||||
IReaderSettings,
|
IReaderSettings,
|
||||||
'readingMode' | 'shouldOffsetDoubleSpreads' | 'readingDirection' | 'readerWidth' | 'pageScaleMode'
|
| 'readingMode'
|
||||||
|
| 'shouldOffsetDoubleSpreads'
|
||||||
|
| 'readingDirection'
|
||||||
|
| 'readerWidth'
|
||||||
|
| 'pageScaleMode'
|
||||||
|
| 'shouldUseInfiniteScroll'
|
||||||
> &
|
> &
|
||||||
Pick<ReaderStateChapters, 'setReaderStateChapters'> & {
|
Pick<ReaderStateChapters, 'setReaderStateChapters'> & {
|
||||||
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>;
|
||||||
@@ -412,6 +418,7 @@ const BaseReaderChapterViewer = ({
|
|||||||
<ReaderInfiniteScrollUpdateChapter
|
<ReaderInfiniteScrollUpdateChapter
|
||||||
readingMode={readingMode}
|
readingMode={readingMode}
|
||||||
readingDirection={readingDirection}
|
readingDirection={readingDirection}
|
||||||
|
shouldUseInfiniteScroll={shouldUseInfiniteScroll}
|
||||||
chapterId={chapterId}
|
chapterId={chapterId}
|
||||||
previousChapterId={previousChapterId}
|
previousChapterId={previousChapterId}
|
||||||
nextChapterId={nextChapterId}
|
nextChapterId={nextChapterId}
|
||||||
|
|||||||
@@ -9,13 +9,14 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
|
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
|
||||||
import { useReaderInfiniteScrollUpdateChapter } from '@/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts';
|
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 { ReaderControls } from '@/modules/reader/services/ReaderControls.ts';
|
||||||
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||||
|
|
||||||
const BaseReaderInfiniteScrollUpdateChapter = ({
|
const BaseReaderInfiniteScrollUpdateChapter = ({
|
||||||
readingMode,
|
readingMode,
|
||||||
readingDirection,
|
readingDirection,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
chapterId,
|
chapterId,
|
||||||
previousChapterId,
|
previousChapterId,
|
||||||
nextChapterId,
|
nextChapterId,
|
||||||
@@ -27,9 +28,8 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
|
|||||||
scrollbarXSize,
|
scrollbarXSize,
|
||||||
scrollbarYSize,
|
scrollbarYSize,
|
||||||
scrollElement,
|
scrollElement,
|
||||||
}: Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'> & {
|
}: Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'> &
|
||||||
readingMode: ReadingMode;
|
Pick<IReaderSettings, 'readingMode' | 'readingDirection' | 'shouldUseInfiniteScroll'> & {
|
||||||
readingDirection: ReadingDirection;
|
|
||||||
chapterId: ChapterIdInfo['id'];
|
chapterId: ChapterIdInfo['id'];
|
||||||
previousChapterId?: ChapterIdInfo['id'];
|
previousChapterId?: ChapterIdInfo['id'];
|
||||||
nextChapterId?: ChapterIdInfo['id'];
|
nextChapterId?: ChapterIdInfo['id'];
|
||||||
@@ -48,6 +48,7 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
|
|||||||
isPreviousChapterVisible,
|
isPreviousChapterVisible,
|
||||||
readingMode,
|
readingMode,
|
||||||
readingDirection,
|
readingDirection,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
openChapter,
|
openChapter,
|
||||||
imageWrapper,
|
imageWrapper,
|
||||||
scrollbarXSize,
|
scrollbarXSize,
|
||||||
@@ -62,6 +63,7 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
|
|||||||
isNextChapterVisible,
|
isNextChapterVisible,
|
||||||
readingMode,
|
readingMode,
|
||||||
readingDirection,
|
readingDirection,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
openChapter,
|
openChapter,
|
||||||
imageWrapper,
|
imageWrapper,
|
||||||
scrollbarXSize,
|
scrollbarXSize,
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ const BaseReaderViewer = forwardRef(
|
|||||||
setTransitionPageMode,
|
setTransitionPageMode,
|
||||||
readingMode,
|
readingMode,
|
||||||
readingDirection,
|
readingDirection,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
readerWidth,
|
readerWidth,
|
||||||
pageScaleMode,
|
pageScaleMode,
|
||||||
shouldOffsetDoubleSpreads,
|
shouldOffsetDoubleSpreads,
|
||||||
@@ -134,6 +135,7 @@ const BaseReaderViewer = forwardRef(
|
|||||||
IReaderSettings,
|
IReaderSettings,
|
||||||
| 'readingMode'
|
| 'readingMode'
|
||||||
| 'readingDirection'
|
| 'readingDirection'
|
||||||
|
| 'shouldUseInfiniteScroll'
|
||||||
| 'readerWidth'
|
| 'readerWidth'
|
||||||
| 'pageScaleMode'
|
| 'pageScaleMode'
|
||||||
| 'shouldOffsetDoubleSpreads'
|
| 'shouldOffsetDoubleSpreads'
|
||||||
@@ -408,6 +410,7 @@ const BaseReaderViewer = forwardRef(
|
|||||||
pageScaleMode={pageScaleMode}
|
pageScaleMode={pageScaleMode}
|
||||||
shouldOffsetDoubleSpreads={shouldOffsetDoubleSpreads}
|
shouldOffsetDoubleSpreads={shouldOffsetDoubleSpreads}
|
||||||
readingDirection={readingDirection}
|
readingDirection={readingDirection}
|
||||||
|
shouldUseInfiniteScroll={shouldUseInfiniteScroll}
|
||||||
updateCurrentPageIndex={isCurrentChapter ? updateCurrentPageIndex : noOp}
|
updateCurrentPageIndex={isCurrentChapter ? updateCurrentPageIndex : noOp}
|
||||||
scrollIntoView={isCurrentChapter && visibleChapters.scrollIntoView}
|
scrollIntoView={isCurrentChapter && visibleChapters.scrollIntoView}
|
||||||
resumeMode={getReaderChapterViewResumeMode(
|
resumeMode={getReaderChapterViewResumeMode(
|
||||||
@@ -465,6 +468,7 @@ export const ReaderViewer = withPropsFrom(
|
|||||||
'setTransitionPageMode',
|
'setTransitionPageMode',
|
||||||
'readingMode',
|
'readingMode',
|
||||||
'readingDirection',
|
'readingDirection',
|
||||||
|
'shouldUseInfiniteScroll',
|
||||||
'readerWidth',
|
'readerWidth',
|
||||||
'pageScaleMode',
|
'pageScaleMode',
|
||||||
'shouldOffsetDoubleSpreads',
|
'shouldOffsetDoubleSpreads',
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ const GLOBAL_READER_SETTING_OBJECT: Record<keyof IReaderSettingsGlobal, undefine
|
|||||||
shouldInformAboutMissingChapter: undefined,
|
shouldInformAboutMissingChapter: undefined,
|
||||||
shouldInformAboutScanlatorChange: undefined,
|
shouldInformAboutScanlatorChange: undefined,
|
||||||
scrollAmount: undefined,
|
scrollAmount: undefined,
|
||||||
|
shouldUseInfiniteScroll: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const GLOBAL_READER_SETTING_KEYS = Object.keys(GLOBAL_READER_SETTING_OBJECT);
|
export const GLOBAL_READER_SETTING_KEYS = Object.keys(GLOBAL_READER_SETTING_OBJECT);
|
||||||
@@ -155,6 +156,7 @@ export const DEFAULT_READER_SETTINGS: IReaderSettings = {
|
|||||||
shouldInformAboutMissingChapter: true,
|
shouldInformAboutMissingChapter: true,
|
||||||
shouldInformAboutScanlatorChange: true,
|
shouldInformAboutScanlatorChange: true,
|
||||||
scrollAmount: ReaderScrollAmount.LARGE,
|
scrollAmount: ReaderScrollAmount.LARGE,
|
||||||
|
shouldUseInfiniteScroll: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const READER_PROGRESS_BAR_POSITION_TO_PLACEMENT: Record<ProgressBarPosition, TooltipProps['placement']> = {
|
export const READER_PROGRESS_BAR_POSITION_TO_PLACEMENT: Record<ProgressBarPosition, TooltipProps['placement']> = {
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ export const useReaderInfiniteScrollUpdateChapter = (
|
|||||||
isChapterToOpenVisible: boolean,
|
isChapterToOpenVisible: boolean,
|
||||||
readingMode: ReadingMode,
|
readingMode: ReadingMode,
|
||||||
readingDirection: ReadingDirection,
|
readingDirection: ReadingDirection,
|
||||||
|
shouldUseInfiniteScroll: boolean,
|
||||||
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>,
|
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>,
|
||||||
image: HTMLElement | null,
|
image: HTMLElement | null,
|
||||||
scrollbarXSize: number,
|
scrollbarXSize: number,
|
||||||
@@ -250,7 +251,11 @@ export const useReaderInfiniteScrollUpdateChapter = (
|
|||||||
image,
|
image,
|
||||||
useCallback(
|
useCallback(
|
||||||
(entries) => {
|
(entries) => {
|
||||||
if (!isContinuousReadingMode(readingMode) || chapterToOpenId === undefined) {
|
if (
|
||||||
|
!shouldUseInfiniteScroll ||
|
||||||
|
!isContinuousReadingMode(readingMode) ||
|
||||||
|
chapterToOpenId === undefined
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,6 +302,7 @@ export const useReaderInfiniteScrollUpdateChapter = (
|
|||||||
isChapterToOpenVisible,
|
isChapterToOpenVisible,
|
||||||
readingMode,
|
readingMode,
|
||||||
readingDirection,
|
readingDirection,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
openChapter,
|
openChapter,
|
||||||
scrollbarXSize,
|
scrollbarXSize,
|
||||||
scrollbarYSize,
|
scrollbarYSize,
|
||||||
|
|||||||
@@ -175,8 +175,12 @@ export class ReaderControls {
|
|||||||
scrollIntoView?: boolean,
|
scrollIntoView?: boolean,
|
||||||
) => void {
|
) => void {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { readingMode, shouldInformAboutMissingChapter, shouldInformAboutScanlatorChange } =
|
const {
|
||||||
ReaderService.useSettings();
|
readingMode,
|
||||||
|
shouldInformAboutMissingChapter,
|
||||||
|
shouldInformAboutScanlatorChange,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
|
} = ReaderService.useSettings();
|
||||||
const {
|
const {
|
||||||
currentChapter,
|
currentChapter,
|
||||||
previousChapter,
|
previousChapter,
|
||||||
@@ -239,7 +243,7 @@ export class ReaderControls {
|
|||||||
const isAlreadyLoaded =
|
const isAlreadyLoaded =
|
||||||
lastLeadingChapterSourceOrder <= chapterToOpen.sourceOrder &&
|
lastLeadingChapterSourceOrder <= chapterToOpen.sourceOrder &&
|
||||||
lastTrailingChapterSourceOrder >= chapterToOpen.sourceOrder;
|
lastTrailingChapterSourceOrder >= chapterToOpen.sourceOrder;
|
||||||
const keepRenderedChapters = !scrollIntoView || isAlreadyLoaded;
|
const keepRenderedChapters = shouldUseInfiniteScroll && (!scrollIntoView || isAlreadyLoaded);
|
||||||
|
|
||||||
if (keepRenderedChapters) {
|
if (keepRenderedChapters) {
|
||||||
setReaderStateChapters((prevState) =>
|
setReaderStateChapters((prevState) =>
|
||||||
@@ -255,7 +259,10 @@ export class ReaderControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openChapter(chapterToOpen, {
|
openChapter(chapterToOpen, {
|
||||||
resumeMode: getReaderOpenChapterResumeMode(isSpecificChapterMode, isPreviousChapter),
|
resumeMode: getReaderOpenChapterResumeMode(
|
||||||
|
isSpecificChapterMode || !keepRenderedChapters,
|
||||||
|
isPreviousChapter,
|
||||||
|
),
|
||||||
updateInitialChapter: !keepRenderedChapters,
|
updateInitialChapter: !keepRenderedChapters,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -274,6 +281,7 @@ export class ReaderControls {
|
|||||||
shouldInformAboutScanlatorChange,
|
shouldInformAboutScanlatorChange,
|
||||||
lastLeadingChapterSourceOrder,
|
lastLeadingChapterSourceOrder,
|
||||||
lastTrailingChapterSourceOrder,
|
lastTrailingChapterSourceOrder,
|
||||||
|
shouldUseInfiniteScroll,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ export interface IReaderSettingsGlobal {
|
|||||||
shouldInformAboutMissingChapter: boolean;
|
shouldInformAboutMissingChapter: boolean;
|
||||||
shouldInformAboutScanlatorChange: boolean;
|
shouldInformAboutScanlatorChange: boolean;
|
||||||
scrollAmount: ReaderScrollAmount;
|
scrollAmount: ReaderScrollAmount;
|
||||||
|
shouldUseInfiniteScroll: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IReaderSettingsManga {
|
export interface IReaderSettingsManga {
|
||||||
|
|||||||
Reference in New Issue
Block a user