Simplify ReaderControls#useOpenChapter

This commit is contained in:
schroda
2025-09-20 19:51:26 +02:00
parent 1c0b982bae
commit f5c7379fc4
6 changed files with 187 additions and 229 deletions

View File

@@ -67,7 +67,6 @@ export const ReaderHotkeys = ({
})); }));
const exitReader = ReaderService.useExit(); const exitReader = ReaderService.useExit();
const openChapter = ReaderControls.useOpenChapter();
const openPage = ReaderControls.useOpenPage(); const openPage = ReaderControls.useOpenPage();
useHotkeys(hotkeys[ReaderHotkey.PREVIOUS_PAGE], () => openPage('previous'), [openPage]); useHotkeys(hotkeys[ReaderHotkey.PREVIOUS_PAGE], () => openPage('previous'), [openPage]);
@@ -96,13 +95,12 @@ export const ReaderHotkeys = ({
readingDirection.value, readingDirection.value,
themeDirection, themeDirection,
scrollElementRef.current, scrollElementRef.current,
openChapter,
getReaderStore().tapZone.setShowPreview, getReaderStore().tapZone.setShowPreview,
scrollAmount, scrollAmount,
); );
}, },
{ preventDefault: true }, { preventDefault: true },
[themeDirection, openChapter], [themeDirection],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.SCROLL_FORWARD], hotkeys[ReaderHotkey.SCROLL_FORWARD],
@@ -128,23 +126,22 @@ export const ReaderHotkeys = ({
readingDirection.value, readingDirection.value,
themeDirection, themeDirection,
scrollElementRef.current, scrollElementRef.current,
openChapter,
getReaderStore().tapZone.setShowPreview, getReaderStore().tapZone.setShowPreview,
scrollAmount, scrollAmount,
); );
}, },
{ preventDefault: true }, { preventDefault: true },
[themeDirection, openChapter], [themeDirection],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.PREVIOUS_CHAPTER], hotkeys[ReaderHotkey.PREVIOUS_CHAPTER],
() => openChapter(getOptionForDirection('previous', 'next', readerThemeDirection)), () => ReaderControls.openChapter(getOptionForDirection('previous', 'next', readerThemeDirection)),
[openChapter, readerThemeDirection], [readerThemeDirection],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.NEXT_CHAPTER], hotkeys[ReaderHotkey.NEXT_CHAPTER],
() => openChapter(getOptionForDirection('next', 'previous', readerThemeDirection)), () => ReaderControls.openChapter(getOptionForDirection('next', 'previous', readerThemeDirection)),
[openChapter, readerThemeDirection], [readerThemeDirection],
); );
useHotkeys(hotkeys[ReaderHotkey.TOGGLE_MENU], () => useHotkeys(hotkeys[ReaderHotkey.TOGGLE_MENU], () =>
getReaderStore().overlay.setIsVisible(!getReaderStore().overlay.isVisible), getReaderStore().overlay.setIsVisible(!getReaderStore().overlay.isVisible),

View File

@@ -7,9 +7,7 @@
*/ */
import { memo } from 'react'; import { memo } from 'react';
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
import { useReaderInfiniteScrollUpdateChapter } from '@/features/reader/infinite-scroll/useReaderInfiniteScrollUpdateChapter.ts'; import { useReaderInfiniteScrollUpdateChapter } from '@/features/reader/infinite-scroll/useReaderInfiniteScrollUpdateChapter.ts';
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts'; import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
const BaseReaderInfiniteScrollUpdateChapter = ({ const BaseReaderInfiniteScrollUpdateChapter = ({
@@ -20,7 +18,6 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
isCurrentChapter, isCurrentChapter,
isNextChapterVisible, isNextChapterVisible,
imageWrapper, imageWrapper,
openChapter,
scrollElement, scrollElement,
}: { }: {
chapterId: ChapterIdInfo['id']; chapterId: ChapterIdInfo['id'];
@@ -30,7 +27,6 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
isCurrentChapter: boolean; isCurrentChapter: boolean;
isNextChapterVisible: boolean; isNextChapterVisible: boolean;
imageWrapper: HTMLElement | null; imageWrapper: HTMLElement | null;
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>;
scrollElement: HTMLElement | null; scrollElement: HTMLElement | null;
}) => { }) => {
useReaderInfiniteScrollUpdateChapter( useReaderInfiniteScrollUpdateChapter(
@@ -39,7 +35,6 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
previousChapterId, previousChapterId,
isCurrentChapter, isCurrentChapter,
isPreviousChapterVisible, isPreviousChapterVisible,
openChapter,
imageWrapper, imageWrapper,
scrollElement, scrollElement,
); );
@@ -49,7 +44,6 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
nextChapterId, nextChapterId,
isCurrentChapter, isCurrentChapter,
isNextChapterVisible, isNextChapterVisible,
openChapter,
imageWrapper, imageWrapper,
scrollElement, scrollElement,
); );
@@ -57,8 +51,4 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
return null; return null;
}; };
export const ReaderInfiniteScrollUpdateChapter = withPropsFrom( export const ReaderInfiniteScrollUpdateChapter = memo(BaseReaderInfiniteScrollUpdateChapter);
memo(BaseReaderInfiniteScrollUpdateChapter),
[() => ({ openChapter: ReaderControls.useOpenChapter() })],
['openChapter'],
);

View File

@@ -7,7 +7,6 @@
*/ */
import { useCallback, useEffect, useMemo } from 'react'; import { useCallback, useEffect, useMemo } from 'react';
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
import { ReadingDirection, ReadingMode } from '@/features/reader/Reader.types.ts'; import { ReadingDirection, ReadingMode } from '@/features/reader/Reader.types.ts';
import { import {
isContinuousReadingMode, isContinuousReadingMode,
@@ -17,6 +16,7 @@ import { READING_DIRECTION_TO_THEME_DIRECTION } from '@/features/reader/settings
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts'; import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
import { useIntersectionObserver } from '@/base/hooks/useIntersectionObserver.tsx'; import { useIntersectionObserver } from '@/base/hooks/useIntersectionObserver.tsx';
import { getReaderStore, useReaderStoreShallow } from '@/features/reader/stores/ReaderStore.ts'; import { getReaderStore, useReaderStoreShallow } from '@/features/reader/stores/ReaderStore.ts';
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
interface ElementIntersection { interface ElementIntersection {
start: boolean; start: boolean;
@@ -242,7 +242,6 @@ export const useReaderInfiniteScrollUpdateChapter = (
chapterToOpenId: number | undefined, chapterToOpenId: number | undefined,
isCurrentChapter: boolean, isCurrentChapter: boolean,
isChapterToOpenVisible: boolean, isChapterToOpenVisible: boolean,
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>,
image: HTMLElement | null, image: HTMLElement | null,
scrollElement: HTMLElement | null, scrollElement: HTMLElement | null,
) => { ) => {
@@ -286,7 +285,7 @@ export const useReaderInfiniteScrollUpdateChapter = (
const loadChapter = loadPreviousChapter || loadNextChapter; const loadChapter = loadPreviousChapter || loadNextChapter;
if (loadChapter) { if (loadChapter) {
openChapter(chapterToOpenId, undefined, false); ReaderControls.openChapter(chapterToOpenId, undefined, false);
} }
}; };
@@ -300,7 +299,6 @@ export const useReaderInfiniteScrollUpdateChapter = (
isCurrentChapter, isCurrentChapter,
isChapterToOpenVisible, isChapterToOpenVisible,
chapterToOpenId, chapterToOpenId,
openChapter,
]); ]);
useIntersectionObserver( useIntersectionObserver(
@@ -347,12 +345,12 @@ export const useReaderInfiniteScrollUpdateChapter = (
const openChapterToOpen = initialOpenPreviousChapter || openNextChapter; const openChapterToOpen = initialOpenPreviousChapter || openNextChapter;
if (openChapterToOpen) { if (openChapterToOpen) {
openChapter(chapterToOpenId, !isChapterToOpenVisible, false); ReaderControls.openChapter(chapterToOpenId, !isChapterToOpenVisible, false);
return; return;
} }
if (openPreviousChapter) { if (openPreviousChapter) {
openChapter(chapterId, false, false); ReaderControls.openChapter(chapterId, false, false);
} }
}, },
[ [
@@ -365,7 +363,6 @@ export const useReaderInfiniteScrollUpdateChapter = (
readingDirection, readingDirection,
shouldUseInfiniteScroll, shouldUseInfiniteScroll,
shouldShowTransitionPage, shouldShowTransitionPage,
openChapter,
], ],
), ),
useMemo( useMemo(

View File

@@ -31,10 +31,8 @@ const BaseReaderNavBarDesktopChapterNavigation = ({
nextChapter, nextChapter,
chapters = [], chapters = [],
readerThemeDirection, readerThemeDirection,
openChapter,
}: Pick<ReaderStateChapters, 'chapters' | 'currentChapter' | 'previousChapter' | 'nextChapter'> & { }: Pick<ReaderStateChapters, 'chapters' | 'currentChapter' | 'previousChapter' | 'nextChapter'> & {
readerThemeDirection: ReturnType<typeof ReaderService.useGetThemeDirection>; readerThemeDirection: ReturnType<typeof ReaderService.useGetThemeDirection>;
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -56,7 +54,7 @@ const BaseReaderNavBarDesktopChapterNavigation = ({
), ),
)} )}
onClick={() => { onClick={() => {
openChapter(getOptionForDirection('previous', 'next', readerThemeDirection)); ReaderControls.openChapter(getOptionForDirection('previous', 'next', readerThemeDirection));
}} }}
disabled={getOptionForDirection(!previousChapter, !nextChapter, readerThemeDirection)} disabled={getOptionForDirection(!previousChapter, !nextChapter, readerThemeDirection)}
/> />
@@ -88,7 +86,7 @@ const BaseReaderNavBarDesktopChapterNavigation = ({
), ),
)} )}
onClick={() => { onClick={() => {
openChapter(getOptionForDirection('next', 'previous', readerThemeDirection)); ReaderControls.openChapter(getOptionForDirection('next', 'previous', readerThemeDirection));
}} }}
disabled={getOptionForDirection(!nextChapter, !previousChapter, readerThemeDirection)} disabled={getOptionForDirection(!nextChapter, !previousChapter, readerThemeDirection)}
/> />
@@ -122,9 +120,6 @@ export const ReaderNavBarDesktopChapterNavigation = withPropsFrom(
() => ({ () => ({
readerThemeDirection: ReaderService.useGetThemeDirection(), readerThemeDirection: ReaderService.useGetThemeDirection(),
}), }),
() => ({
openChapter: ReaderControls.useOpenChapter(),
}),
], ],
['readerThemeDirection', 'openChapter'], ['readerThemeDirection'],
); );

View File

@@ -28,8 +28,8 @@ import { ReaderProgressBarSlotMobile } from '@/features/reader/overlay/progress-
import { applyStyles } from '@/base/utils/ApplyStyles.ts'; import { applyStyles } from '@/base/utils/ApplyStyles.ts';
import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx'; import { useResizeObserver } from '@/base/hooks/useResizeObserver.tsx';
import { getProgressBarPosition } from '@/features/reader/settings/ReaderSettings.utils.tsx'; import { getProgressBarPosition } from '@/features/reader/settings/ReaderSettings.utils.tsx';
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
import { useReaderStore, useReaderStoreShallow } from '@/features/reader/stores/ReaderStore.ts'; import { useReaderStore, useReaderStoreShallow } from '@/features/reader/stores/ReaderStore.ts';
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
const PROGRESS_BAR_POSITION_TO_SLIDE_DIRECTION: Record<ProgressBarPosition, SlideProps['direction']> = { const PROGRESS_BAR_POSITION_TO_SLIDE_DIRECTION: Record<ProgressBarPosition, SlideProps['direction']> = {
[ProgressBarPosition.BOTTOM]: 'up', [ProgressBarPosition.BOTTOM]: 'up',
@@ -48,7 +48,6 @@ const BaseMobileReaderProgressBar = ({
topOffset?: number; topOffset?: number;
bottomOffset?: number; bottomOffset?: number;
}) => { }) => {
const openChapter = ReaderControls.useOpenChapter();
const scrollbar = useReaderStoreShallow((state) => state.scrollbar); const scrollbar = useReaderStoreShallow((state) => state.scrollbar);
const isVisible = useReaderStore((state) => state.overlay.isVisible); const isVisible = useReaderStore((state) => state.overlay.isVisible);
const { currentPageIndex, pages } = useReaderStoreShallow((state) => ({ const { currentPageIndex, pages } = useReaderStoreShallow((state) => ({
@@ -251,7 +250,7 @@ const BaseMobileReaderProgressBar = ({
}} }}
> >
<IconButton <IconButton
onClick={() => openChapter('previous')} onClick={() => ReaderControls.openChapter('previous')}
disabled={!previousChapter} disabled={!previousChapter}
sx={{ sx={{
backgroundColor: (theme) => alpha(theme.palette.background.paper, 0.85), backgroundColor: (theme) => alpha(theme.palette.background.paper, 0.85),
@@ -324,7 +323,7 @@ const BaseMobileReaderProgressBar = ({
slots={progressBarCurrentPage} slots={progressBarCurrentPage}
/> />
<IconButton <IconButton
onClick={() => openChapter('next')} onClick={() => ReaderControls.openChapter('next')}
disabled={!nextChapter} disabled={!nextChapter}
sx={{ backgroundColor: (theme) => alpha(theme.palette.background.paper, 0.85), boxShadow: 2 }} sx={{ backgroundColor: (theme) => alpha(theme.palette.background.paper, 0.85), boxShadow: 2 }}
> >

View File

@@ -91,7 +91,6 @@ export class ReaderControls {
readingDirection: ReadingDirection, readingDirection: ReadingDirection,
themeDirection: Direction, themeDirection: Direction,
element: HTMLElement, element: HTMLElement,
openChapter: ReturnType<(typeof ReaderControls)['useOpenChapter']>,
setShowPreview: TReaderTapZoneContext['setShowPreview'], setShowPreview: TReaderTapZoneContext['setShowPreview'],
scrollAmountPercentage: number = ReaderScrollAmount.LARGE, scrollAmountPercentage: number = ReaderScrollAmount.LARGE,
): void { ): void {
@@ -129,12 +128,12 @@ export class ReaderControls {
scrollToOptions: ScrollToOptions, scrollToOptions: ScrollToOptions,
) => { ) => {
if (isAtStartForDirection && offset === ScrollOffset.BACKWARD && isContinuousReadingModeActive) { if (isAtStartForDirection && offset === ScrollOffset.BACKWARD && isContinuousReadingModeActive) {
openChapter('previous'); ReaderControls.openChapter('previous');
return; return;
} }
if (isAtEndForDirection && offset === ScrollOffset.FORWARD && isContinuousReadingModeActive) { if (isAtEndForDirection && offset === ScrollOffset.FORWARD && isContinuousReadingModeActive) {
openChapter('next'); ReaderControls.openChapter('next');
return; return;
} }
@@ -158,105 +157,99 @@ export class ReaderControls {
} }
} }
static useOpenChapter(): ( static openChapter(
offset: 'previous' | 'next' | ChapterIdInfo['id'], offset: 'previous' | 'next' | ChapterIdInfo['id'],
doTransitionCheck?: boolean, doTransitionCheck: boolean = true,
scrollIntoView?: boolean, scrollIntoView: boolean = true,
) => void { ): void {
return useCallback((offset, doTransitionCheck = true, scrollIntoView = true) => { const {
const { chapters: {
chapters: { currentChapter,
currentChapter, previousChapter,
previousChapter, nextChapter,
nextChapter, chapters,
chapters, visibleChapters: { lastLeadingChapterSourceOrder, lastTrailingChapterSourceOrder },
visibleChapters: { lastLeadingChapterSourceOrder, lastTrailingChapterSourceOrder }, setReaderStateChapters,
setReaderStateChapters, },
}, settings: { shouldInformAboutMissingChapter, shouldInformAboutScanlatorChange, shouldUseInfiniteScroll },
settings: { } = getReaderStore();
shouldInformAboutMissingChapter,
shouldInformAboutScanlatorChange,
shouldUseInfiniteScroll,
},
} = getReaderStore();
if (!currentChapter) { if (!currentChapter) {
return; return;
} }
const isSpecificChapterMode = typeof offset === 'number'; const isSpecificChapterMode = typeof offset === 'number';
const isPreviousOffset = offset === 'previous'; const isPreviousOffset = offset === 'previous';
const doesPreviousChapterExist = isPreviousOffset && !!previousChapter; const doesPreviousChapterExist = isPreviousOffset && !!previousChapter;
const doesNextChapterExist = !isPreviousOffset && !!nextChapter; const doesNextChapterExist = !isPreviousOffset && !!nextChapter;
const canOpenNextChapter = isSpecificChapterMode || doesPreviousChapterExist || doesNextChapterExist; const canOpenNextChapter = isSpecificChapterMode || doesPreviousChapterExist || doesNextChapterExist;
if (!canOpenNextChapter) { if (!canOpenNextChapter) {
return; return;
} }
const doOpenChapter = async () => { const doOpenChapter = async () => {
const chapterToOpen = (() => { const chapterToOpen = (() => {
if (isSpecificChapterMode) { if (isSpecificChapterMode) {
return chapters.find((chapter) => chapter.id === offset); return chapters.find((chapter) => chapter.id === offset);
}
if (isPreviousOffset) {
return previousChapter;
}
return nextChapter;
})();
if (!chapterToOpen) {
return;
} }
const isPreviousChapter = chapterToOpen.sourceOrder < currentChapter.sourceOrder; if (isPreviousOffset) {
return previousChapter;
}
try { return nextChapter;
if (doTransitionCheck) { })();
await ReaderControls.checkNextChapterConsistency(
isPreviousChapter ? 'previous' : 'next',
currentChapter,
chapterToOpen,
shouldInformAboutMissingChapter,
shouldInformAboutScanlatorChange,
);
}
const isAlreadyLoaded = if (!chapterToOpen) {
lastLeadingChapterSourceOrder <= chapterToOpen.sourceOrder && return;
lastTrailingChapterSourceOrder >= chapterToOpen.sourceOrder; }
const keepRenderedChapters = shouldUseInfiniteScroll && (!scrollIntoView || isAlreadyLoaded);
if (keepRenderedChapters) { const isPreviousChapter = chapterToOpen.sourceOrder < currentChapter.sourceOrder;
setReaderStateChapters((prevState) =>
updateReaderStateVisibleChapters(
isPreviousChapter,
prevState,
chapterToOpen.sourceOrder,
scrollIntoView,
isPreviousChapter ? false : undefined,
!isPreviousChapter ? false : undefined,
),
);
}
ReaderService.navigateToChapter(chapterToOpen, { try {
resumeMode: getReaderOpenChapterResumeMode( if (doTransitionCheck) {
isSpecificChapterMode || !keepRenderedChapters, await ReaderControls.checkNextChapterConsistency(
isPreviousChapter ? 'previous' : 'next',
currentChapter,
chapterToOpen,
shouldInformAboutMissingChapter,
shouldInformAboutScanlatorChange,
);
}
const isAlreadyLoaded =
lastLeadingChapterSourceOrder <= chapterToOpen.sourceOrder &&
lastTrailingChapterSourceOrder >= chapterToOpen.sourceOrder;
const keepRenderedChapters = shouldUseInfiniteScroll && (!scrollIntoView || isAlreadyLoaded);
if (keepRenderedChapters) {
setReaderStateChapters((prevState) =>
updateReaderStateVisibleChapters(
isPreviousChapter, isPreviousChapter,
prevState,
chapterToOpen.sourceOrder,
scrollIntoView,
isPreviousChapter ? false : undefined,
!isPreviousChapter ? false : undefined,
), ),
updateInitialChapter: !keepRenderedChapters, );
});
} catch (error) {
defaultPromiseErrorHandler('ReaderControls#useOpenChapter#doOpenChapter:')(error);
} }
};
doOpenChapter().catch(defaultPromiseErrorHandler('ReaderControls#useOpenChapter')); ReaderService.navigateToChapter(chapterToOpen, {
}, []); resumeMode: getReaderOpenChapterResumeMode(
isSpecificChapterMode || !keepRenderedChapters,
isPreviousChapter,
),
updateInitialChapter: !keepRenderedChapters,
});
} catch (error) {
defaultPromiseErrorHandler('ReaderControls#useOpenChapter#doOpenChapter:')(error);
}
};
doOpenChapter().catch(defaultPromiseErrorHandler('ReaderControls#useOpenChapter'));
} }
private static async checkNextChapterConsistency( private static async checkNextChapterConsistency(
@@ -323,112 +316,101 @@ export class ReaderControls {
forceDirection?: Direction, forceDirection?: Direction,
hideOverlay?: boolean, hideOverlay?: boolean,
) => void { ) => void {
const openChapter = ReaderControls.useOpenChapter(); return useCallback((page, forceDirection, hideOverlay: boolean = true) => {
const {
pages: { currentPageIndex, setPageToScrollToIndex, pages, transitionPageMode, setTransitionPageMode },
settings: { readingDirection, readingMode, shouldShowTransitionPage },
} = getReaderStore();
return useCallback( const direction = READING_DIRECTION_TO_THEME_DIRECTION[readingDirection.value];
(page, forceDirection, hideOverlay: boolean = true) => {
const {
pages: {
currentPageIndex,
setPageToScrollToIndex,
pages,
transitionPageMode,
setTransitionPageMode,
},
settings: { readingDirection, readingMode, shouldShowTransitionPage },
} = getReaderStore();
const direction = READING_DIRECTION_TO_THEME_DIRECTION[readingDirection.value]; const convertedPage = getOptionForDirection(
page,
page === 'previous' ? 'next' : 'previous',
forceDirection ?? direction,
);
const convertedPage = getOptionForDirection( const currentPage = getPage(currentPageIndex, pages);
page, const previousPageIndex = getNextPageIndex('previous', currentPage.pagesIndex, pages);
page === 'previous' ? 'next' : 'previous', const nextPageIndex = getNextPageIndex('next', currentPage.pagesIndex, pages);
forceDirection ?? direction, const indexOfFirstPage = getNextIndexFromPage(pages[0]);
const indexOfLastPage = getNextIndexFromPage(pages[pages.length - 1]);
const isFirstPage = currentPage.primary.index === 0;
const isLastPage = currentPageIndex === indexOfLastPage;
const isATransitionPageVisibleFlag = isATransitionPageVisible(transitionPageMode, readingMode.value);
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode.value);
if (hideOverlay) {
getReaderStore().overlay.setIsVisible(false);
getReaderStore().tapZone.setShowPreview(false);
}
const hideTransitionPage = () => setTransitionPageMode(ReaderTransitionPageMode.NONE);
if (typeof page === 'number') {
setPageToScrollToIndex(page);
hideTransitionPage();
return;
}
const areContinuousPagerTransitionPagesVisible =
isContinuousReadingModeActive && isATransitionPageVisibleFlag;
const isPreviousTransitionPageVisible =
(!isContinuousReadingModeActive && transitionPageMode === ReaderTransitionPageMode.PREVIOUS) ||
areContinuousPagerTransitionPagesVisible;
const isNextTransitionPageVisible =
(!isContinuousReadingModeActive && transitionPageMode === ReaderTransitionPageMode.NEXT) ||
areContinuousPagerTransitionPagesVisible;
const shouldOpenPreviousChapter =
isFirstPage &&
(!shouldShowTransitionPage || isPreviousTransitionPageVisible) &&
convertedPage === 'previous' &&
!!getReaderStore().chapters.previousChapter;
if (shouldOpenPreviousChapter) {
ReaderControls.openChapter('previous');
return;
}
const shouldOpenNextChapter =
isLastPage &&
(!shouldShowTransitionPage || isNextTransitionPageVisible) &&
convertedPage === 'next' &&
!!getReaderStore().chapters.nextChapter;
if (shouldOpenNextChapter) {
ReaderControls.openChapter('next');
return;
}
const isPreviousMode = convertedPage === 'previous';
const isNextMode = convertedPage === 'next';
const closePreviousTransitionPage = isPreviousTransitionPageVisible && isNextMode;
const closeNextTransitionPage = isNextTransitionPageVisible && isPreviousMode;
const needToHideTransitionPage =
isATransitionPageVisibleFlag &&
!isContinuousReadingModeActive &&
(closePreviousTransitionPage || closeNextTransitionPage);
if (needToHideTransitionPage) {
hideTransitionPage();
setPageToScrollToIndex(isPreviousTransitionPageVisible ? indexOfFirstPage : indexOfLastPage);
return;
}
const needToOpenTransitionPage =
((isFirstPage && isPreviousMode) || (isLastPage && isNextMode)) && !isContinuousReadingModeActive;
if (needToOpenTransitionPage) {
setTransitionPageMode(
isPreviousMode ? ReaderTransitionPageMode.PREVIOUS : ReaderTransitionPageMode.NEXT,
); );
return;
}
const currentPage = getPage(currentPageIndex, pages); setPageToScrollToIndex(isPreviousMode ? previousPageIndex : nextPageIndex);
const previousPageIndex = getNextPageIndex('previous', currentPage.pagesIndex, pages); }, []);
const nextPageIndex = getNextPageIndex('next', currentPage.pagesIndex, pages);
const indexOfFirstPage = getNextIndexFromPage(pages[0]);
const indexOfLastPage = getNextIndexFromPage(pages[pages.length - 1]);
const isFirstPage = currentPage.primary.index === 0;
const isLastPage = currentPageIndex === indexOfLastPage;
const isATransitionPageVisibleFlag = isATransitionPageVisible(transitionPageMode, readingMode.value);
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode.value);
if (hideOverlay) {
getReaderStore().overlay.setIsVisible(false);
getReaderStore().tapZone.setShowPreview(false);
}
const hideTransitionPage = () => setTransitionPageMode(ReaderTransitionPageMode.NONE);
if (typeof page === 'number') {
setPageToScrollToIndex(page);
hideTransitionPage();
return;
}
const areContinuousPagerTransitionPagesVisible =
isContinuousReadingModeActive && isATransitionPageVisibleFlag;
const isPreviousTransitionPageVisible =
(!isContinuousReadingModeActive && transitionPageMode === ReaderTransitionPageMode.PREVIOUS) ||
areContinuousPagerTransitionPagesVisible;
const isNextTransitionPageVisible =
(!isContinuousReadingModeActive && transitionPageMode === ReaderTransitionPageMode.NEXT) ||
areContinuousPagerTransitionPagesVisible;
const shouldOpenPreviousChapter =
isFirstPage &&
(!shouldShowTransitionPage || isPreviousTransitionPageVisible) &&
convertedPage === 'previous' &&
!!getReaderStore().chapters.previousChapter;
if (shouldOpenPreviousChapter) {
openChapter('previous');
return;
}
const shouldOpenNextChapter =
isLastPage &&
(!shouldShowTransitionPage || isNextTransitionPageVisible) &&
convertedPage === 'next' &&
!!getReaderStore().chapters.nextChapter;
if (shouldOpenNextChapter) {
openChapter('next');
return;
}
const isPreviousMode = convertedPage === 'previous';
const isNextMode = convertedPage === 'next';
const closePreviousTransitionPage = isPreviousTransitionPageVisible && isNextMode;
const closeNextTransitionPage = isNextTransitionPageVisible && isPreviousMode;
const needToHideTransitionPage =
isATransitionPageVisibleFlag &&
!isContinuousReadingModeActive &&
(closePreviousTransitionPage || closeNextTransitionPage);
if (needToHideTransitionPage) {
hideTransitionPage();
setPageToScrollToIndex(isPreviousTransitionPageVisible ? indexOfFirstPage : indexOfLastPage);
return;
}
const needToOpenTransitionPage =
((isFirstPage && isPreviousMode) || (isLastPage && isNextMode)) && !isContinuousReadingModeActive;
if (needToOpenTransitionPage) {
setTransitionPageMode(
isPreviousMode ? ReaderTransitionPageMode.PREVIOUS : ReaderTransitionPageMode.NEXT,
);
return;
}
setPageToScrollToIndex(isPreviousMode ? previousPageIndex : nextPageIndex);
},
[openChapter],
);
} }
static useUpdateCurrentPageIndex(): ( static useUpdateCurrentPageIndex(): (
@@ -554,7 +536,6 @@ export class ReaderControls {
): (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void { ): (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void {
const { direction: themeDirection } = useTheme(); const { direction: themeDirection } = useTheme();
const openPage = ReaderControls.useOpenPage(); const openPage = ReaderControls.useOpenPage();
const openChapter = ReaderControls.useOpenChapter();
return useCallback( return useCallback(
(e) => { (e) => {
@@ -589,7 +570,6 @@ export class ReaderControls {
readingDirection.value, readingDirection.value,
themeDirection, themeDirection,
scrollElement, scrollElement,
openChapter,
getReaderStore().tapZone.setShowPreview, getReaderStore().tapZone.setShowPreview,
scrollAmount, scrollAmount,
); );
@@ -601,7 +581,7 @@ export class ReaderControls {
throw new Error(`Unexpected "TapZoneRegionType" (${action})`); throw new Error(`Unexpected "TapZoneRegionType" (${action})`);
} }
}, },
[scrollElement, openPage, openChapter, themeDirection], [scrollElement, openPage, themeDirection],
); );
} }