fix: adjust scroll offset to account for header/footer bars when paginating in scroll mode, closes #1181 (#1193)

This commit is contained in:
Huang Xin
2025-05-19 16:34:05 +08:00
committed by GitHub
parent 554d786105
commit 12d93ba749
3 changed files with 39 additions and 12 deletions
@@ -17,6 +17,7 @@ import { useSidebarStore } from '@/store/sidebarStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import { eventDispatcher } from '@/utils/event';
import { viewPagination } from '../hooks/usePagination';
import { saveViewSettings } from '../utils/viewSettingsHelper';
import { PageInfo } from '@/types/book';
import Button from '@/components/Button';
@@ -77,11 +78,11 @@ const FooterBar: React.FC<FooterBarProps> = ({
};
const handleGoPrev = () => {
view?.goLeft();
viewPagination(view, viewSettings, 'left');
};
const handleGoNext = () => {
view?.goRight();
viewPagination(view, viewSettings, 'right');
};
const handleGoBack = () => {
@@ -9,6 +9,7 @@ import { getStyles } from '@/utils/style';
import { tauriHandleToggleFullScreen, tauriQuitApp } from '@/utils/window';
import { eventDispatcher } from '@/utils/event';
import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL, ZOOM_STEP } from '@/services/constants';
import { viewPagination } from './usePagination';
interface UseBookShortcutsProps {
sideBarBookKey: string | null;
@@ -41,11 +42,13 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) =
};
const goLeft = () => {
getView(sideBarBookKey)?.goLeft();
const viewSettings = getViewSettings(sideBarBookKey ?? '');
viewPagination(getView(sideBarBookKey), viewSettings, 'left');
};
const goRight = () => {
getView(sideBarBookKey)?.goRight();
const viewSettings = getViewSettings(sideBarBookKey ?? '');
viewPagination(getView(sideBarBookKey), viewSettings, 'right');
};
const goPrev = () => {
@@ -1,6 +1,7 @@
import { useEffect } from 'react';
import { useEnv } from '@/context/EnvContext';
import { FoliateView } from '@/types/view';
import { ViewSettings } from '@/types/book';
import { useReaderStore } from '@/store/readerStore';
import { useDeviceControlStore } from '@/store/deviceStore';
import { eventDispatcher } from '@/utils/event';
@@ -9,6 +10,27 @@ import { tauriGetWindowLogicalPosition } from '@/utils/window';
export type ScrollSource = 'touch' | 'mouse';
export const viewPagination = (
view: FoliateView | null,
viewSettings: ViewSettings | null | undefined,
side: 'left' | 'right',
) => {
if (!view || !viewSettings) return;
const renderer = view.renderer;
if (renderer.scrolled) {
if (view.book.dir === 'rtl') {
side = side === 'left' ? 'right' : 'left';
}
const { size } = renderer;
const showHeader = viewSettings.showHeader && viewSettings.showBarsOnScroll;
const showFooter = viewSettings.showFooter && viewSettings.showBarsOnScroll;
const distance = size - (showHeader ? 44 : 0) - (showFooter ? 44 : 0);
return side === 'left' ? view.prev(distance) : view.next(distance);
} else {
return side === 'left' ? view.goLeft() : view.goRight();
}
};
export const usePagination = (
bookKey: string,
viewRef: React.MutableRefObject<FoliateView | null>,
@@ -64,15 +86,15 @@ export const usePagination = (
}
if (!viewSettings.disableClick! && screenX >= viewCenterX) {
if (viewSettings.swapClickArea) {
viewRef.current?.goLeft();
viewPagination(viewRef.current, viewSettings, 'left');
} else {
viewRef.current?.goRight();
viewPagination(viewRef.current, viewSettings, 'right');
}
} else if (!viewSettings.disableClick! && screenX < viewCenterX) {
if (viewSettings.swapClickArea) {
viewRef.current?.goRight();
viewPagination(viewRef.current, viewSettings, 'right');
} else {
viewRef.current?.goLeft();
viewPagination(viewRef.current, viewSettings, 'left');
}
}
}
@@ -100,9 +122,9 @@ export const usePagination = (
if (viewSettings?.volumeKeysToFlip) {
setHoveredBookKey('');
if (keyName === 'VolumeUp') {
viewRef.current?.goLeft();
viewPagination(viewRef.current, viewSettings, 'left');
} else if (keyName === 'VolumeDown') {
viewRef.current?.goRight();
viewPagination(viewRef.current, viewSettings, 'right');
}
}
} else {
@@ -111,10 +133,11 @@ export const usePagination = (
const width = window.innerWidth;
const leftThreshold = width * 0.5;
const rightThreshold = width * 0.5;
const viewSettings = getViewSettings(bookKey);
if (clientX < leftThreshold) {
viewRef.current?.goLeft();
viewPagination(viewRef.current, viewSettings, 'left');
} else if (clientX > rightThreshold) {
viewRef.current?.goRight();
viewPagination(viewRef.current, viewSettings, 'right');
}
}
}