Add setting to apply chapter list filters in reader
This commit is contained in:
@@ -995,7 +995,9 @@
|
|||||||
"reading_mode": "Reading mode",
|
"reading_mode": "Reading mode",
|
||||||
"show_page_number": "Show page number",
|
"show_page_number": "Show page number",
|
||||||
"skip_dup_chapters": "Skip duplicate chapters",
|
"skip_dup_chapters": "Skip duplicate chapters",
|
||||||
"static_navigation": "Static navigation"
|
"skip_filtered_chapters": "Skip filtered chapters",
|
||||||
|
"static_navigation": "Static navigation",
|
||||||
|
"unchangeable_in_reader": "Setting can not be changed while the reader is opened"
|
||||||
},
|
},
|
||||||
"overlay_mode": "Overlay mode",
|
"overlay_mode": "Overlay mode",
|
||||||
"page_scale": {
|
"page_scale": {
|
||||||
|
|||||||
@@ -92,18 +92,25 @@ const sortChapters = <T extends TChapterSort>(
|
|||||||
return sortedChapters;
|
return sortedChapters;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TChapterFilter = TChapterSort & ChapterReadInfo & ChapterDownloadInfo & ChapterBookmarkInfo & ChapterScanlatorInfo;
|
type TChapterFilter = ChapterReadInfo & ChapterDownloadInfo & ChapterBookmarkInfo & ChapterScanlatorInfo;
|
||||||
export function filterAndSortChapters<Chapters extends TChapterFilter>(
|
export function filterChapters<Chapters extends TChapterFilter>(
|
||||||
chapters: Chapters[],
|
chapters: Chapters[],
|
||||||
options: ChapterListOptions,
|
options: ChapterListOptions,
|
||||||
): Chapters[] {
|
): Chapters[] {
|
||||||
const filtered = chapters.filter(
|
return chapters.filter(
|
||||||
(chp) =>
|
(chp) =>
|
||||||
unreadFilter(options.unread, chp) &&
|
unreadFilter(options.unread, chp) &&
|
||||||
downloadFilter(options.downloaded, chp) &&
|
downloadFilter(options.downloaded, chp) &&
|
||||||
bookmarkedFilter(options.bookmarked, chp) &&
|
bookmarkedFilter(options.bookmarked, chp) &&
|
||||||
scanlatorFilter(options.excludedScanlators, chp),
|
scanlatorFilter(options.excludedScanlators, chp),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filterAndSortChapters<Chapters extends TChapterSort & TChapterFilter>(
|
||||||
|
chapters: Chapters[],
|
||||||
|
options: ChapterListOptions,
|
||||||
|
): Chapters[] {
|
||||||
|
const filtered = filterChapters(chapters, options);
|
||||||
|
|
||||||
return sortChapters(filtered, options);
|
return sortChapters(filtered, options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ import {
|
|||||||
CHAPTER_ACTION_TO_CONFIRMATION_REQUIRED,
|
CHAPTER_ACTION_TO_CONFIRMATION_REQUIRED,
|
||||||
CHAPTER_ACTION_TO_TRANSLATION,
|
CHAPTER_ACTION_TO_TRANSLATION,
|
||||||
} from '@/modules/chapter/Chapter.constants.ts';
|
} from '@/modules/chapter/Chapter.constants.ts';
|
||||||
|
import { GqlMetaHolder } from '@/modules/metadata/Metadata.types.ts';
|
||||||
|
|
||||||
export const FALLBACK_MANGA: MangaIdInfo = { id: -1 };
|
export const FALLBACK_MANGA: MangaIdInfo & GqlMetaHolder = { id: -1 };
|
||||||
|
|
||||||
export const GLOBAL_READER_SETTINGS_MANGA: MangaIdInfo = { id: -2 };
|
export const GLOBAL_READER_SETTINGS_MANGA: MangaIdInfo = { id: -2 };
|
||||||
|
|
||||||
|
|||||||
@@ -259,6 +259,9 @@ export const APP_METADATA: Record<
|
|||||||
shouldSkipDupChapters: {
|
shouldSkipDupChapters: {
|
||||||
convert: convertToBoolean,
|
convert: convertToBoolean,
|
||||||
},
|
},
|
||||||
|
shouldSkipFilteredChapters: {
|
||||||
|
convert: convertToBoolean,
|
||||||
|
},
|
||||||
isStaticNav: {
|
isStaticNav: {
|
||||||
convert: convertToBoolean,
|
convert: convertToBoolean,
|
||||||
},
|
},
|
||||||
@@ -452,6 +455,7 @@ export const GLOBAL_METADATA_KEYS: AppMetadataKeys[] = [
|
|||||||
'exitMode',
|
'exitMode',
|
||||||
'customFilter',
|
'customFilter',
|
||||||
'shouldSkipDupChapters',
|
'shouldSkipDupChapters',
|
||||||
|
'shouldSkipFilteredChapters',
|
||||||
'hotkeys',
|
'hotkeys',
|
||||||
'shouldShowTransitionPage',
|
'shouldShowTransitionPage',
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ const BaseReaderSettingsTabs = ({
|
|||||||
<ReaderBehaviourSettings
|
<ReaderBehaviourSettings
|
||||||
settings={settings}
|
settings={settings}
|
||||||
updateSetting={(...args) => updateSetting(...args)}
|
updateSetting={(...args) => updateSetting(...args)}
|
||||||
isDefaultable
|
// @ts-expect-error - TS2322: Type boolean is not assignable to type true
|
||||||
|
isDefaultable={!areDefaultSettings}
|
||||||
onDefault={(...args) => deleteSetting?.(...args)}
|
onDefault={(...args) => deleteSetting?.(...args)}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export const ReaderBehaviourSettings = ({
|
|||||||
settings,
|
settings,
|
||||||
updateSetting,
|
updateSetting,
|
||||||
onDefault,
|
onDefault,
|
||||||
|
isDefaultable,
|
||||||
}: {
|
}: {
|
||||||
settings: IReaderSettingsWithDefaultFlag;
|
settings: IReaderSettingsWithDefaultFlag;
|
||||||
updateSetting: (
|
updateSetting: (
|
||||||
@@ -50,6 +51,21 @@ export const ReaderBehaviourSettings = ({
|
|||||||
checked={settings.shouldSkipDupChapters}
|
checked={settings.shouldSkipDupChapters}
|
||||||
onChange={(_, checked) => updateSetting('shouldSkipDupChapters', checked)}
|
onChange={(_, checked) => updateSetting('shouldSkipDupChapters', checked)}
|
||||||
/>
|
/>
|
||||||
|
<CheckboxInput
|
||||||
|
label={
|
||||||
|
<Box>
|
||||||
|
<Typography>{t('reader.settings.label.skip_filtered_chapters')}</Typography>
|
||||||
|
{isDefaultable && (
|
||||||
|
<Typography variant="body2" color="textDisabled">
|
||||||
|
{t('reader.settings.label.unchangeable_in_reader')}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
checked={settings.shouldSkipFilteredChapters}
|
||||||
|
onChange={(_, checked) => updateSetting('shouldSkipFilteredChapters', checked)}
|
||||||
|
disabled={isDefaultable}
|
||||||
|
/>
|
||||||
{isOffsetDoubleSpreadPagesEditable(settings.readingMode.value) && (
|
{isOffsetDoubleSpreadPagesEditable(settings.readingMode.value) && (
|
||||||
<CheckboxInput
|
<CheckboxInput
|
||||||
label={t('reader.settings.label.offset_double_spread')}
|
label={t('reader.settings.label.offset_double_spread')}
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ const GLOBAL_READER_SETTING_OBJECT: Record<keyof IReaderSettingsGlobal, undefine
|
|||||||
exitMode: undefined,
|
exitMode: undefined,
|
||||||
customFilter: undefined,
|
customFilter: undefined,
|
||||||
shouldSkipDupChapters: undefined,
|
shouldSkipDupChapters: undefined,
|
||||||
|
shouldSkipFilteredChapters: undefined,
|
||||||
progressBarType: undefined,
|
progressBarType: undefined,
|
||||||
progressBarSize: undefined,
|
progressBarSize: undefined,
|
||||||
progressBarPosition: undefined,
|
progressBarPosition: undefined,
|
||||||
@@ -170,6 +171,7 @@ export const DEFAULT_READER_SETTINGS: IReaderSettings = {
|
|||||||
shouldStretchPage: false,
|
shouldStretchPage: false,
|
||||||
shouldOffsetDoubleSpreads: false,
|
shouldOffsetDoubleSpreads: false,
|
||||||
shouldSkipDupChapters: true,
|
shouldSkipDupChapters: true,
|
||||||
|
shouldSkipFilteredChapters: false,
|
||||||
shouldShowPageNumber: true,
|
shouldShowPageNumber: true,
|
||||||
isStaticNav: false,
|
isStaticNav: false,
|
||||||
readingDirection: ReadingDirection.LTR,
|
readingDirection: ReadingDirection.LTR,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { createContext, useContext } from 'react';
|
|||||||
import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
|
import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
|
||||||
|
|
||||||
export const READER_STATE_CHAPTERS_DEFAULTS: Omit<ReaderStateChapters, 'setReaderStateChapters'> = {
|
export const READER_STATE_CHAPTERS_DEFAULTS: Omit<ReaderStateChapters, 'setReaderStateChapters'> = {
|
||||||
mangaChapters: [],
|
|
||||||
chapters: [],
|
chapters: [],
|
||||||
isCurrentChapterReady: false,
|
isCurrentChapterReady: false,
|
||||||
visibleChapters: {
|
visibleChapters: {
|
||||||
|
|||||||
@@ -18,14 +18,20 @@ import {
|
|||||||
ReaderStateChapters,
|
ReaderStateChapters,
|
||||||
} from '@/modules/reader/types/Reader.types.ts';
|
} from '@/modules/reader/types/Reader.types.ts';
|
||||||
import { READER_STATE_CHAPTERS_DEFAULTS } from '@/modules/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
import { READER_STATE_CHAPTERS_DEFAULTS } from '@/modules/reader/contexts/state/ReaderStateChaptersContext.tsx';
|
||||||
|
import { filterChapters } from '@/modules/chapter/utils/ChapterList.util.tsx';
|
||||||
|
import { ChapterListOptions } from '@/modules/chapter/Chapter.types.ts';
|
||||||
|
import { getReaderChapterFromCache } from '@/modules/reader/utils/Reader.utils.ts';
|
||||||
|
|
||||||
export const useReaderSetChaptersState = (
|
export const useReaderSetChaptersState = (
|
||||||
chaptersResponse: ReturnType<typeof requestManager.useGetMangaChapters<GetChaptersReaderQuery>>,
|
chaptersResponse: ReturnType<typeof requestManager.useGetMangaChapters<GetChaptersReaderQuery>>,
|
||||||
chapterSourceOrder: number,
|
chapterSourceOrder: number,
|
||||||
|
mangaChapters: ReaderStateChapters['mangaChapters'],
|
||||||
initialChapter: ReaderStateChapters['initialChapter'],
|
initialChapter: ReaderStateChapters['initialChapter'],
|
||||||
chapterForDuplicatesHandling: ReaderStateChapters['chapterForDuplicatesHandling'],
|
chapterForDuplicatesHandling: ReaderStateChapters['chapterForDuplicatesHandling'],
|
||||||
setReaderStateChapters: ReaderStateChapters['setReaderStateChapters'],
|
setReaderStateChapters: ReaderStateChapters['setReaderStateChapters'],
|
||||||
shouldSkipDupChapters: IReaderSettings['shouldSkipDupChapters'],
|
shouldSkipDupChapters: IReaderSettings['shouldSkipDupChapters'],
|
||||||
|
shouldSkipFilteredChapters: IReaderSettings['shouldSkipFilteredChapters'],
|
||||||
|
chapterListOptions: ChapterListOptions,
|
||||||
) => {
|
) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const locationState = useLocation<ReaderOpenChapterLocationState>().state;
|
const locationState = useLocation<ReaderOpenChapterLocationState>().state;
|
||||||
@@ -41,33 +47,30 @@ export const useReaderSetChaptersState = (
|
|||||||
const newInitialChapter = finalInitialChapter ?? newCurrentChapter;
|
const newInitialChapter = finalInitialChapter ?? newCurrentChapter;
|
||||||
const newChapterForDuplicatesHandling = chapterForDuplicatesHandling ?? newCurrentChapter;
|
const newChapterForDuplicatesHandling = chapterForDuplicatesHandling ?? newCurrentChapter;
|
||||||
|
|
||||||
const nextChapter =
|
const visibleChapters = (() => {
|
||||||
newMangaChapters &&
|
|
||||||
newCurrentChapter &&
|
|
||||||
Chapters.getNextChapter(newCurrentChapter, newMangaChapters, {
|
|
||||||
offset: DirectionOffset.NEXT,
|
|
||||||
skipDupe: shouldSkipDupChapters,
|
|
||||||
skipDupeChapter: newChapterForDuplicatesHandling,
|
|
||||||
});
|
|
||||||
const previousChapter =
|
|
||||||
newMangaChapters &&
|
|
||||||
newCurrentChapter &&
|
|
||||||
Chapters.getNextChapter(newCurrentChapter, newMangaChapters, {
|
|
||||||
offset: DirectionOffset.PREVIOUS,
|
|
||||||
skipDupe: shouldSkipDupChapters,
|
|
||||||
skipDupeChapter: newChapterForDuplicatesHandling,
|
|
||||||
});
|
|
||||||
const newChapters = (() => {
|
|
||||||
if (!newMangaChapters || !newChapterForDuplicatesHandling) {
|
if (!newMangaChapters || !newChapterForDuplicatesHandling) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldSkipDupChapters) {
|
const filteredChapters = shouldSkipFilteredChapters
|
||||||
return Chapters.removeDuplicates(newChapterForDuplicatesHandling, newMangaChapters);
|
? filterChapters(mangaChapters ?? newMangaChapters, chapterListOptions)
|
||||||
}
|
: newMangaChapters;
|
||||||
|
const uniqueChapters = shouldSkipDupChapters
|
||||||
|
? Chapters.removeDuplicates(newChapterForDuplicatesHandling, filteredChapters)
|
||||||
|
: filteredChapters;
|
||||||
|
|
||||||
return newMangaChapters;
|
return uniqueChapters.map((chapter) => getReaderChapterFromCache(chapter.id)!);
|
||||||
})();
|
})();
|
||||||
|
const nextChapter =
|
||||||
|
newCurrentChapter &&
|
||||||
|
Chapters.getNextChapter(newCurrentChapter, visibleChapters, {
|
||||||
|
offset: DirectionOffset.NEXT,
|
||||||
|
});
|
||||||
|
const previousChapter =
|
||||||
|
newCurrentChapter &&
|
||||||
|
Chapters.getNextChapter(newCurrentChapter, visibleChapters, {
|
||||||
|
offset: DirectionOffset.PREVIOUS,
|
||||||
|
});
|
||||||
|
|
||||||
const hasInitialChapterChanged = newInitialChapter != null && newInitialChapter.id !== finalInitialChapter?.id;
|
const hasInitialChapterChanged = newInitialChapter != null && newInitialChapter.id !== finalInitialChapter?.id;
|
||||||
|
|
||||||
@@ -77,10 +80,11 @@ export const useReaderSetChaptersState = (
|
|||||||
|
|
||||||
setReaderStateChapters((prevState) => {
|
setReaderStateChapters((prevState) => {
|
||||||
const hasCurrentChapterChanged = newCurrentChapter?.id !== prevState.currentChapter?.id;
|
const hasCurrentChapterChanged = newCurrentChapter?.id !== prevState.currentChapter?.id;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
mangaChapters: newMangaChapters ?? [],
|
mangaChapters: prevState.mangaChapters ?? newMangaChapters,
|
||||||
chapters: newChapters,
|
chapters: visibleChapters,
|
||||||
initialChapter: newInitialChapter,
|
initialChapter: newInitialChapter,
|
||||||
chapterForDuplicatesHandling: newChapterForDuplicatesHandling,
|
chapterForDuplicatesHandling: newChapterForDuplicatesHandling,
|
||||||
currentChapter: newCurrentChapter,
|
currentChapter: newCurrentChapter,
|
||||||
@@ -104,5 +108,12 @@ export const useReaderSetChaptersState = (
|
|||||||
: prevState.visibleChapters,
|
: prevState.visibleChapters,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, [chaptersResponse.data?.chapters.nodes, chapterSourceOrder, shouldSkipDupChapters, finalInitialChapter]);
|
}, [
|
||||||
|
chaptersResponse.data?.chapters.nodes,
|
||||||
|
chapterSourceOrder,
|
||||||
|
shouldSkipDupChapters,
|
||||||
|
shouldSkipFilteredChapters,
|
||||||
|
finalInitialChapter,
|
||||||
|
chapterListOptions,
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ import { useReaderSetSettingsState } from '@/modules/reader/hooks/useReaderSetSe
|
|||||||
import { useReaderShowSettingPreviewOnChange } from '@/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts';
|
import { useReaderShowSettingPreviewOnChange } from '@/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts';
|
||||||
import { useReaderSetChaptersState } from '@/modules/reader/hooks/useReaderSetChaptersState.ts';
|
import { useReaderSetChaptersState } from '@/modules/reader/hooks/useReaderSetChaptersState.ts';
|
||||||
import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
|
import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
|
||||||
|
import { useChapterListOptions } from '@/modules/chapter/utils/ChapterList.util.tsx';
|
||||||
|
import { FALLBACK_MANGA } from '@/modules/manga/Manga.constants.ts';
|
||||||
|
|
||||||
const BaseReader = ({
|
const BaseReader = ({
|
||||||
setOverride,
|
setOverride,
|
||||||
@@ -61,6 +63,7 @@ const BaseReader = ({
|
|||||||
manga,
|
manga,
|
||||||
setManga,
|
setManga,
|
||||||
shouldSkipDupChapters,
|
shouldSkipDupChapters,
|
||||||
|
shouldSkipFilteredChapters,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
readingMode,
|
readingMode,
|
||||||
tapZoneLayout,
|
tapZoneLayout,
|
||||||
@@ -68,6 +71,7 @@ const BaseReader = ({
|
|||||||
shouldShowReadingModePreview,
|
shouldShowReadingModePreview,
|
||||||
shouldShowTapZoneLayoutPreview,
|
shouldShowTapZoneLayoutPreview,
|
||||||
setSettings,
|
setSettings,
|
||||||
|
mangaChapters,
|
||||||
initialChapter,
|
initialChapter,
|
||||||
chapterForDuplicatesHandling,
|
chapterForDuplicatesHandling,
|
||||||
currentChapter,
|
currentChapter,
|
||||||
@@ -87,12 +91,20 @@ const BaseReader = ({
|
|||||||
Pick<TReaderStateSettingsContext, 'setSettings'> &
|
Pick<TReaderStateSettingsContext, 'setSettings'> &
|
||||||
Pick<
|
Pick<
|
||||||
IReaderSettings,
|
IReaderSettings,
|
||||||
'shouldSkipDupChapters' | 'backgroundColor' | 'shouldShowReadingModePreview' | 'shouldShowTapZoneLayoutPreview'
|
| 'shouldSkipDupChapters'
|
||||||
|
| 'shouldSkipFilteredChapters'
|
||||||
|
| 'backgroundColor'
|
||||||
|
| 'shouldShowReadingModePreview'
|
||||||
|
| 'shouldShowTapZoneLayoutPreview'
|
||||||
> &
|
> &
|
||||||
Pick<IReaderSettingsWithDefaultFlag, 'readingMode' | 'tapZoneLayout' | 'tapZoneInvertMode'> &
|
Pick<IReaderSettingsWithDefaultFlag, 'readingMode' | 'tapZoneLayout' | 'tapZoneInvertMode'> &
|
||||||
Pick<
|
Pick<
|
||||||
ReaderStateChapters,
|
ReaderStateChapters,
|
||||||
'initialChapter' | 'chapterForDuplicatesHandling' | 'currentChapter' | 'setReaderStateChapters'
|
| 'mangaChapters'
|
||||||
|
| 'initialChapter'
|
||||||
|
| 'chapterForDuplicatesHandling'
|
||||||
|
| 'currentChapter'
|
||||||
|
| 'setReaderStateChapters'
|
||||||
> &
|
> &
|
||||||
Pick<
|
Pick<
|
||||||
ReaderStatePages,
|
ReaderStatePages,
|
||||||
@@ -134,6 +146,7 @@ const BaseReader = ({
|
|||||||
settings: defaultSettings,
|
settings: defaultSettings,
|
||||||
request: defaultSettingsResponse,
|
request: defaultSettingsResponse,
|
||||||
} = useDefaultReaderSettings();
|
} = useDefaultReaderSettings();
|
||||||
|
const chapterListOptions = useChapterListOptions(manga ?? FALLBACK_MANGA);
|
||||||
|
|
||||||
const isLoading =
|
const isLoading =
|
||||||
currentChapter === undefined ||
|
currentChapter === undefined ||
|
||||||
@@ -183,10 +196,13 @@ const BaseReader = ({
|
|||||||
useReaderSetChaptersState(
|
useReaderSetChaptersState(
|
||||||
chaptersResponse,
|
chaptersResponse,
|
||||||
chapterSourceOrder,
|
chapterSourceOrder,
|
||||||
|
mangaChapters,
|
||||||
initialChapter,
|
initialChapter,
|
||||||
chapterForDuplicatesHandling,
|
chapterForDuplicatesHandling,
|
||||||
setReaderStateChapters,
|
setReaderStateChapters,
|
||||||
shouldSkipDupChapters,
|
shouldSkipDupChapters,
|
||||||
|
shouldSkipFilteredChapters,
|
||||||
|
chapterListOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
@@ -296,12 +312,14 @@ export const Reader = withPropsFrom(
|
|||||||
() => {
|
() => {
|
||||||
const {
|
const {
|
||||||
shouldSkipDupChapters,
|
shouldSkipDupChapters,
|
||||||
|
shouldSkipFilteredChapters,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
shouldShowReadingModePreview,
|
shouldShowReadingModePreview,
|
||||||
shouldShowTapZoneLayoutPreview,
|
shouldShowTapZoneLayoutPreview,
|
||||||
} = ReaderService.useSettingsWithoutDefaultFlag();
|
} = ReaderService.useSettingsWithoutDefaultFlag();
|
||||||
return {
|
return {
|
||||||
shouldSkipDupChapters,
|
shouldSkipDupChapters,
|
||||||
|
shouldSkipFilteredChapters,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
shouldShowReadingModePreview,
|
shouldShowReadingModePreview,
|
||||||
shouldShowTapZoneLayoutPreview,
|
shouldShowTapZoneLayoutPreview,
|
||||||
@@ -323,6 +341,7 @@ export const Reader = withPropsFrom(
|
|||||||
'manga',
|
'manga',
|
||||||
'setManga',
|
'setManga',
|
||||||
'shouldSkipDupChapters',
|
'shouldSkipDupChapters',
|
||||||
|
'shouldSkipFilteredChapters',
|
||||||
'backgroundColor',
|
'backgroundColor',
|
||||||
'readingMode',
|
'readingMode',
|
||||||
'tapZoneLayout',
|
'tapZoneLayout',
|
||||||
@@ -330,6 +349,7 @@ export const Reader = withPropsFrom(
|
|||||||
'shouldShowReadingModePreview',
|
'shouldShowReadingModePreview',
|
||||||
'shouldShowTapZoneLayoutPreview',
|
'shouldShowTapZoneLayoutPreview',
|
||||||
'setSettings',
|
'setSettings',
|
||||||
|
'mangaChapters',
|
||||||
'initialChapter',
|
'initialChapter',
|
||||||
'chapterForDuplicatesHandling',
|
'chapterForDuplicatesHandling',
|
||||||
'currentChapter',
|
'currentChapter',
|
||||||
|
|||||||
@@ -475,32 +475,22 @@ export class ReaderControls {
|
|||||||
endReached?: boolean,
|
endReached?: boolean,
|
||||||
) => void {
|
) => void {
|
||||||
const { currentPageIndex, setCurrentPageIndex } = userReaderStatePagesContext();
|
const { currentPageIndex, setCurrentPageIndex } = userReaderStatePagesContext();
|
||||||
const {
|
const { currentChapter, chapters, previousChapter, nextChapter, visibleChapters, setReaderStateChapters } =
|
||||||
chapterForDuplicatesHandling,
|
useReaderStateChaptersContext();
|
||||||
currentChapter,
|
|
||||||
previousChapter,
|
|
||||||
nextChapter,
|
|
||||||
mangaChapters,
|
|
||||||
visibleChapters,
|
|
||||||
setReaderStateChapters,
|
|
||||||
} = useReaderStateChaptersContext();
|
|
||||||
const updateChapter = ReaderService.useUpdateChapter();
|
const updateChapter = ReaderService.useUpdateChapter();
|
||||||
const { shouldSkipDupChapters } = ReaderService.useSettings();
|
|
||||||
const {
|
const {
|
||||||
settings: { downloadAheadLimit },
|
settings: { downloadAheadLimit },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const nextChapters = useMemo(() => {
|
const nextChapters = useMemo(() => {
|
||||||
if (!chapterForDuplicatesHandling || !currentChapter) {
|
if (!currentChapter) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Chapters.getNextChapters(currentChapter, mangaChapters, {
|
return Chapters.getNextChapters(currentChapter, chapters, {
|
||||||
offset: DirectionOffset.NEXT,
|
offset: DirectionOffset.NEXT,
|
||||||
skipDupe: shouldSkipDupChapters,
|
|
||||||
skipDupeChapter: chapterForDuplicatesHandling,
|
|
||||||
});
|
});
|
||||||
}, [chapterForDuplicatesHandling?.id, currentChapter?.id, mangaChapters, shouldSkipDupChapters]);
|
}, [currentChapter?.id, chapters]);
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(pageIndex, debounceChapterUpdate = true, endReached = false) => {
|
(pageIndex, debounceChapterUpdate = true, endReached = false) => {
|
||||||
|
|||||||
@@ -157,27 +157,25 @@ export class ReaderService {
|
|||||||
|
|
||||||
static useUpdateChapter(): (patch: UpdateChapterPatchInput) => void {
|
static useUpdateChapter(): (patch: UpdateChapterPatchInput) => void {
|
||||||
const { manga } = useReaderStateMangaContext();
|
const { manga } = useReaderStateMangaContext();
|
||||||
const { chapterForDuplicatesHandling, currentChapter, mangaChapters } = useReaderStateChaptersContext();
|
const { currentChapter, mangaChapters, chapters } = useReaderStateChaptersContext();
|
||||||
const { shouldSkipDupChapters } = ReaderService.useSettings();
|
const { shouldSkipDupChapters } = ReaderService.useSettings();
|
||||||
const {
|
const {
|
||||||
settings: { deleteChaptersWhileReading, deleteChaptersWithBookmark, updateProgressAfterReading },
|
settings: { deleteChaptersWhileReading, deleteChaptersWithBookmark, updateProgressAfterReading },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const previousChapters = useMemo(() => {
|
const previousChapters = useMemo(() => {
|
||||||
if (!chapterForDuplicatesHandling || !currentChapter) {
|
if (!currentChapter) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Chapters.getNextChapters(currentChapter, mangaChapters, {
|
return Chapters.getNextChapters(currentChapter, chapters, {
|
||||||
offset: DirectionOffset.PREVIOUS,
|
offset: DirectionOffset.PREVIOUS,
|
||||||
skipDupe: shouldSkipDupChapters,
|
|
||||||
skipDupeChapter: chapterForDuplicatesHandling,
|
|
||||||
});
|
});
|
||||||
}, [chapterForDuplicatesHandling?.id, currentChapter?.id, mangaChapters, shouldSkipDupChapters]);
|
}, [currentChapter?.id, chapters]);
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(patch) => {
|
(patch) => {
|
||||||
if (!manga || !currentChapter) {
|
if (!manga || !currentChapter || !mangaChapters) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export interface IReaderSettingsGlobal {
|
|||||||
exitMode: ReaderExitMode;
|
exitMode: ReaderExitMode;
|
||||||
customFilter: ReaderCustomFilter;
|
customFilter: ReaderCustomFilter;
|
||||||
shouldSkipDupChapters: boolean;
|
shouldSkipDupChapters: boolean;
|
||||||
|
shouldSkipFilteredChapters: boolean;
|
||||||
progressBarType: ProgressBarType;
|
progressBarType: ProgressBarType;
|
||||||
/**
|
/**
|
||||||
* pixel
|
* pixel
|
||||||
@@ -202,14 +203,19 @@ export interface IReaderSettingsWithDefaultFlag
|
|||||||
|
|
||||||
export interface ReaderStateChapters {
|
export interface ReaderStateChapters {
|
||||||
/**
|
/**
|
||||||
* all chapters of the manga
|
* All chapters of the manga with their state preserved from the initial reader load.
|
||||||
*/
|
|
||||||
mangaChapters: TChapterReader[];
|
|
||||||
/**
|
|
||||||
* actual chapters that have been filtered
|
|
||||||
*
|
*
|
||||||
* optional filters:
|
* The state needs to be preserved so that chapter state changes do not lead to chapters getting filtered out.
|
||||||
* - removed duplicate chapters
|
* E.g., in case read chapters are filtered out. This would then lead to the removal of the current chapter
|
||||||
|
* after the end of the chapter is reached.
|
||||||
|
*/
|
||||||
|
mangaChapters?: TChapterReader[];
|
||||||
|
/**
|
||||||
|
* Actual chapters that have been filtered
|
||||||
|
*
|
||||||
|
* Optional filters:
|
||||||
|
* - Removed duplicate chapters
|
||||||
|
* - Manga chapter list filters
|
||||||
*/
|
*/
|
||||||
chapters: TChapterReader[];
|
chapters: TChapterReader[];
|
||||||
chapterForDuplicatesHandling?: TChapterReader | null;
|
chapterForDuplicatesHandling?: TChapterReader | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user