Immediately open previous/next chapter on reader nav bar button click

The logic didn't handle cases were the next/previous chapter wasn't loaded yet, which lead to the load happening in the background without any user feedback.
This commit is contained in:
schroda
2025-04-02 02:27:01 +02:00
parent 7a7a0dfa9c
commit 642708b8b3
5 changed files with 37 additions and 25 deletions

View File

@@ -161,7 +161,7 @@ const BaseReaderViewer = forwardRef(
ref: ForwardedRef<HTMLDivElement | null>,
) => {
const { direction: themeDirection } = useTheme();
const { resumeMode } = useLocation<ReaderOpenChapterLocationState>().state ?? {
const { resumeMode = ReaderResumeMode.START } = useLocation<ReaderOpenChapterLocationState>().state ?? {
resumeMode: ReaderResumeMode.START,
};

View File

@@ -177,8 +177,14 @@ export class ReaderControls {
const { t } = useTranslation();
const { readingMode, shouldInformAboutMissingChapter, shouldInformAboutScanlatorChange } =
ReaderService.useSettings();
const { currentChapter, previousChapter, nextChapter, chapters, setReaderStateChapters } =
useReaderStateChaptersContext();
const {
currentChapter,
previousChapter,
nextChapter,
chapters,
visibleChapters: { lastLeadingChapterSourceOrder, lastTrailingChapterSourceOrder },
setReaderStateChapters,
} = useReaderStateChaptersContext();
const openChapter = ReaderService.useNavigateToChapter();
@@ -230,21 +236,27 @@ export class ReaderControls {
);
}
setReaderStateChapters((prevState) =>
updateReaderStateVisibleChapters(
isPreviousChapter,
prevState,
chapterToOpen.sourceOrder,
scrollIntoView,
isPreviousChapter ? false : undefined,
!isPreviousChapter ? false : undefined,
),
);
const isAlreadyLoaded =
lastLeadingChapterSourceOrder <= chapterToOpen.sourceOrder &&
lastTrailingChapterSourceOrder >= chapterToOpen.sourceOrder;
openChapter(
chapterToOpen,
getReaderOpenChapterResumeMode(isSpecificChapterMode, isPreviousChapter),
);
if (isAlreadyLoaded) {
setReaderStateChapters((prevState) =>
updateReaderStateVisibleChapters(
isPreviousChapter,
prevState,
chapterToOpen.sourceOrder,
scrollIntoView,
isPreviousChapter ? false : undefined,
!isPreviousChapter ? false : undefined,
),
);
}
openChapter(chapterToOpen, {
resumeMode: getReaderOpenChapterResumeMode(isSpecificChapterMode, isPreviousChapter),
updateInitialChapter: !isAlreadyLoaded,
});
} catch (error) {
defaultPromiseErrorHandler('ReaderControls#useOpenChapter#doOpenChapter:')(error);
}
@@ -259,6 +271,8 @@ export class ReaderControls {
readingMode.value,
shouldInformAboutMissingChapter,
shouldInformAboutScanlatorChange,
lastLeadingChapterSourceOrder,
lastTrailingChapterSourceOrder,
],
);
}

View File

@@ -16,8 +16,8 @@ import {
IReaderSettings,
IReaderSettingsWithDefaultFlag,
ReaderExitMode,
ReaderOpenChapterLocationState,
ReaderOverlayMode,
ReaderResumeMode,
ReaderStateChapters,
ReadingDirection,
ReadingMode,
@@ -78,15 +78,13 @@ export class ReaderService {
return ReaderService.chapterUpdateQueues.get(id)!;
}
static useNavigateToChapter(): (chapter: TChapterReader, resumeMode?: ReaderResumeMode) => void {
static useNavigateToChapter(): (chapter: TChapterReader, state?: ReaderOpenChapterLocationState) => void {
const navigate = useNavigate();
return useCallback((chapter, resumeMode) => {
return useCallback((chapter, state) => {
navigate(Chapters.getReaderUrl(chapter), {
replace: true,
state: {
resumeMode,
},
state,
});
}, []);
}

View File

@@ -318,7 +318,7 @@ export enum ReaderResumeMode {
}
export interface ReaderOpenChapterLocationState {
resumeMode: ReaderResumeMode;
resumeMode?: ReaderResumeMode;
updateInitialChapter?: boolean;
}

View File

@@ -301,7 +301,7 @@ export const getReaderChapterViewResumeMode = (
isLeadingChapter: boolean,
isTrailingChapter: boolean,
forcedResumeMode: ReaderResumeMode | undefined,
resumeMode: ReaderResumeMode = ReaderResumeMode.START,
resumeMode: ReaderResumeMode,
): ReaderResumeMode => {
if (isCurrentChapter && forcedResumeMode !== undefined) {
return forcedResumeMode;