Simplify ReaderControls#useHandleClick

This commit is contained in:
schroda
2025-09-20 20:00:16 +02:00
parent ca5920919e
commit 5730690ae6
3 changed files with 43 additions and 62 deletions

View File

@@ -8,7 +8,6 @@
import { useHotkeys as useHotKeysHook, useHotkeysContext } from 'react-hotkeys-hook'; import { useHotkeys as useHotKeysHook, useHotkeysContext } from 'react-hotkeys-hook';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useTheme } from '@mui/material/styles';
import { HOTKEY_SCOPES } from '@/features/hotkeys/Hotkeys.constants.ts'; import { HOTKEY_SCOPES } from '@/features/hotkeys/Hotkeys.constants.ts';
import { ReaderService } from '@/features/reader/services/ReaderService.ts'; import { ReaderService } from '@/features/reader/services/ReaderService.ts';
import { IReaderSettings, ReaderHotkey } from '@/features/reader/Reader.types.ts'; import { IReaderSettings, ReaderHotkey } from '@/features/reader/Reader.types.ts';
@@ -59,7 +58,6 @@ export const ReaderHotkeys = ({
}: { }: {
scrollElementRef: React.MutableRefObject<HTMLElement | null>; scrollElementRef: React.MutableRefObject<HTMLElement | null>;
}) => { }) => {
const { direction: themeDirection } = useTheme();
const readerThemeDirection = ReaderService.useGetThemeDirection(); const readerThemeDirection = ReaderService.useGetThemeDirection();
const { enableScope, disableScope } = useHotkeysContext(); const { enableScope, disableScope } = useHotkeysContext();
const { hotkeys } = useReaderStoreShallow((state) => ({ const { hotkeys } = useReaderStoreShallow((state) => ({
@@ -91,14 +89,12 @@ export const ReaderHotkeys = ({
CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION[readingMode.value], CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION[readingMode.value],
readingMode.value, readingMode.value,
readingDirection.value, readingDirection.value,
themeDirection,
scrollElementRef.current, scrollElementRef.current,
getReaderStore().tapZone.setShowPreview, getReaderStore().tapZone.setShowPreview,
scrollAmount, scrollAmount,
); );
}, },
{ preventDefault: true }, { preventDefault: true },
[themeDirection],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.SCROLL_FORWARD], hotkeys[ReaderHotkey.SCROLL_FORWARD],
@@ -122,14 +118,12 @@ export const ReaderHotkeys = ({
CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION[readingMode.value], CONTINUOUS_READING_MODE_TO_SCROLL_DIRECTION[readingMode.value],
readingMode.value, readingMode.value,
readingDirection.value, readingDirection.value,
themeDirection,
scrollElementRef.current, scrollElementRef.current,
getReaderStore().tapZone.setShowPreview, getReaderStore().tapZone.setShowPreview,
scrollAmount, scrollAmount,
); );
}, },
{ preventDefault: true }, { preventDefault: true },
[themeDirection],
); );
useHotkeys( useHotkeys(
hotkeys[ReaderHotkey.PREVIOUS_CHAPTER], hotkeys[ReaderHotkey.PREVIOUS_CHAPTER],

View File

@@ -7,7 +7,7 @@
*/ */
import { MutableRefObject, RefObject, useCallback, useEffect } from 'react'; import { MutableRefObject, RefObject, useCallback, useEffect } from 'react';
import { Direction, useTheme } from '@mui/material/styles'; import { Direction } from '@mui/material/styles';
import { t as translate } from 'i18next'; import { t as translate } from 'i18next';
import { import {
getNextIndexFromPage, getNextIndexFromPage,
@@ -16,7 +16,7 @@ import {
getPageForMousePos, getPageForMousePos,
getProgressBarPositionInfo, getProgressBarPositionInfo,
} from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx'; } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx';
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts'; import { getCurrentTheme, getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
import { ReaderService } from '@/features/reader/services/ReaderService.ts'; import { ReaderService } from '@/features/reader/services/ReaderService.ts';
import { import {
PageInViewportType, PageInViewportType,
@@ -89,7 +89,6 @@ export class ReaderControls {
direction: ScrollDirection, direction: ScrollDirection,
readingMode: ReadingMode, readingMode: ReadingMode,
readingDirection: ReadingDirection, readingDirection: ReadingDirection,
themeDirection: Direction,
element: HTMLElement, element: HTMLElement,
setShowPreview: TReaderTapZoneContext['setShowPreview'], setShowPreview: TReaderTapZoneContext['setShowPreview'],
scrollAmountPercentage: number = ReaderScrollAmount.LARGE, scrollAmountPercentage: number = ReaderScrollAmount.LARGE,
@@ -99,7 +98,7 @@ export class ReaderControls {
} }
const themeDirectionOfReadingDirection = READING_DIRECTION_TO_THEME_DIRECTION[readingDirection]; const themeDirectionOfReadingDirection = READING_DIRECTION_TO_THEME_DIRECTION[readingDirection];
const areReadingDirectionsEqual = themeDirection === themeDirectionOfReadingDirection; const areReadingDirectionsEqual = getCurrentTheme().direction === themeDirectionOfReadingDirection;
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode); const isContinuousReadingModeActive = isContinuousReadingMode(readingMode);
const isAtStartY = Math.abs(element.scrollTop) <= 1; const isAtStartY = Math.abs(element.scrollTop) <= 1;
@@ -522,57 +521,47 @@ export class ReaderControls {
updateCurrentPageIndex(firstVisibleImageIndex, firstVisibleImageIndex !== lastPageIndex); updateCurrentPageIndex(firstVisibleImageIndex, firstVisibleImageIndex !== lastPageIndex);
} }
static useHandleClick( static handleClick(scrollElement: HTMLElement | null, e: React.MouseEvent<HTMLDivElement, MouseEvent>): void {
scrollElement: HTMLElement | null, if (!scrollElement) {
): (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void { return;
const { direction: themeDirection } = useTheme(); }
return useCallback( const { readingMode, readingDirection, isStaticNav, scrollAmount } = getReaderStore().settings;
(e) => {
if (!scrollElement) { const rect = e.currentTarget.getBoundingClientRect();
return; const rectRelativeX = e.clientX - rect.left;
const rectRelativeY = e.clientY - rect.top;
const action = ReaderTapZoneService.getAction(rectRelativeX, rectRelativeY);
getReaderStore().tapZone.setShowPreview(false);
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode.value);
const scrollDirection =
readingMode.value === ReadingMode.CONTINUOUS_HORIZONTAL ? ScrollDirection.X : ScrollDirection.Y;
switch (action) {
case TapZoneRegionType.MENU:
getReaderStore().overlay.setIsVisible(isStaticNav || !getReaderStore().overlay.isVisible);
break;
case TapZoneRegionType.PREVIOUS:
case TapZoneRegionType.NEXT:
if (isContinuousReadingModeActive) {
ReaderControls.scroll(
action === TapZoneRegionType.PREVIOUS ? ScrollOffset.BACKWARD : ScrollOffset.FORWARD,
scrollDirection,
readingMode.value,
readingDirection.value,
scrollElement,
getReaderStore().tapZone.setShowPreview,
scrollAmount,
);
} else {
ReaderControls.openPage(action === TapZoneRegionType.PREVIOUS ? 'previous' : 'next', 'ltr');
} }
break;
const { readingMode, readingDirection, isStaticNav, scrollAmount } = getReaderStore().settings; default:
throw new Error(`Unexpected "TapZoneRegionType" (${action})`);
const rect = e.currentTarget.getBoundingClientRect(); }
const rectRelativeX = e.clientX - rect.left;
const rectRelativeY = e.clientY - rect.top;
const action = ReaderTapZoneService.getAction(rectRelativeX, rectRelativeY);
getReaderStore().tapZone.setShowPreview(false);
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode.value);
const scrollDirection =
readingMode.value === ReadingMode.CONTINUOUS_HORIZONTAL ? ScrollDirection.X : ScrollDirection.Y;
switch (action) {
case TapZoneRegionType.MENU:
getReaderStore().overlay.setIsVisible(isStaticNav || !getReaderStore().overlay.isVisible);
break;
case TapZoneRegionType.PREVIOUS:
case TapZoneRegionType.NEXT:
if (isContinuousReadingModeActive) {
ReaderControls.scroll(
action === TapZoneRegionType.PREVIOUS ? ScrollOffset.BACKWARD : ScrollOffset.FORWARD,
scrollDirection,
readingMode.value,
readingDirection.value,
themeDirection,
scrollElement,
getReaderStore().tapZone.setShowPreview,
scrollAmount,
);
} else {
ReaderControls.openPage(action === TapZoneRegionType.PREVIOUS ? 'previous' : 'next', 'ltr');
}
break;
default:
throw new Error(`Unexpected "TapZoneRegionType" (${action})`);
}
},
[scrollElement, themeDirection],
);
} }
static useHandleProgressDragging( static useHandleProgressDragging(

View File

@@ -175,8 +175,6 @@ const BaseReaderViewer = forwardRef(
scrollbar.setYSize(scrollbarYSize); scrollbar.setYSize(scrollbarYSize);
}, [scrollbarXSize, scrollbarYSize]); }, [scrollbarXSize, scrollbarYSize]);
const handleClick = ReaderControls.useHandleClick(scrollElementRef.current);
const imageRefs = useRef<(HTMLElement | null)[]>(pages.map(() => null)); const imageRefs = useRef<(HTMLElement | null)[]>(pages.map(() => null));
const [{ minChapterViewWidth, minChapterViewHeight, minChapterSizeSourceChapterId }, setChapterViewerSize] = const [{ minChapterViewWidth, minChapterViewHeight, minChapterSizeSourceChapterId }, setChapterViewerSize] =
useState({ useState({
@@ -320,7 +318,7 @@ const BaseReaderViewer = forwardRef(
}), }),
}), }),
}} }}
onClick={(e) => !isDragging && handleClick(e)} onClick={(e) => !isDragging && ReaderControls.handleClick(scrollElementRef.current, e)}
onScroll={() => onScroll={() =>
ReaderControls.updateCurrentPageOnScroll( ReaderControls.updateCurrentPageOnScroll(
imageRefs, imageRefs,