Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/app/src/components/reader/FoliateViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ export const FoliateViewer = forwardRef<FoliateViewerHandle, FoliateViewerProps>
);

// --- Hooks ---
usePagination({ bookKey, viewRef, containerRef });
usePagination({ bookKey, viewRef, containerRef, isFixedLayout });
useBookShortcuts({
bookKey,
viewRef,
Expand Down
17 changes: 17 additions & 0 deletions packages/app/src/components/reader/ReaderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ function useAutoHideControls(
keepVisible = false,
isDoublePage = false,
isScrollMode = false,
isFixedLayout = false,
) {
const [isVisible, setIsVisible] = useState(true);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
Expand Down Expand Up @@ -273,10 +274,23 @@ function useAutoHideControls(
viewWidth,
isDoublePage,
isScrollMode,
isFixedLayout,
leftNavEnd,
rightNavStart,
});

if (isFixedLayout && !isVisible) {
console.log("[ReaderTap][reader:action]", {
bookKey,
source,
action: "show-controls",
fraction,
isDoublePage,
});
showAndScheduleHide();
return;
}

if (isScrollMode) {
toggleControls();
return;
Expand Down Expand Up @@ -328,6 +342,8 @@ function useAutoHideControls(
showAndScheduleHide,
isDoublePage,
isScrollMode,
isFixedLayout,
isVisible,
]);

// Mouse enter/leave handlers for toolbar area
Expand Down Expand Up @@ -867,6 +883,7 @@ export function ReaderView({ bookId, tabId }: ReaderViewProps) {
keepControlsVisible,
(viewSettings.paginatedLayout ?? "double") === "double",
viewSettings.viewMode === "scroll",
isFixedLayout,
);
const isDoublePage = (viewSettings.paginatedLayout ?? "double") === "double";
const toolbarVisible = controlsVisible || isToolbarPinned;
Expand Down
41 changes: 39 additions & 2 deletions packages/core/src/hooks/reader/usePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface UsePaginationOptions {
bookKey: string;
viewRef: React.RefObject<FoliateView | null>;
containerRef: React.RefObject<HTMLDivElement | null>;
isFixedLayout?: boolean;
}

/** Minimum cooldown after a page turn (ms) */
Expand All @@ -19,7 +20,39 @@ const WHEEL_MIN_COOLDOWN_MS = 350;
/** After the last wheel event, wait this long before unlocking (ms). */
const WHEEL_IDLE_MS = 200;

export function usePagination({ bookKey, viewRef, containerRef }: UsePaginationOptions) {
function getScrollableDistance(element: HTMLElement, axis: "x" | "y") {
return axis === "x"
? Math.max(0, element.scrollWidth - element.clientWidth)
: Math.max(0, element.scrollHeight - element.clientHeight);
}

function scrollFixedLayoutPage(view: FoliateView, deltaY: number, deltaX = 0) {
const renderer = view.renderer as HTMLElement | undefined;
if (!renderer || renderer.getAttribute("spread") !== "none") return false;

const maxY = getScrollableDistance(renderer, "y");
const maxX = getScrollableDistance(renderer, "x");
if (maxY <= 1 && maxX <= 1) return false;

const beforeTop = renderer.scrollTop;
const beforeLeft = renderer.scrollLeft;
const top = maxY > 1 ? deltaY : 0;
const left = maxX > 1 ? deltaX : 0;
if (Math.abs(top) < 1 && Math.abs(left) < 1) return false;

renderer.scrollBy({ top, left, behavior: "auto" });
return (
Math.abs(renderer.scrollTop - beforeTop) > 0.5 ||
Math.abs(renderer.scrollLeft - beforeLeft) > 0.5
);
}

export function usePagination({
bookKey,
viewRef,
containerRef,
isFixedLayout = false,
}: UsePaginationOptions) {
const wheelLocked = useRef(false);
const idleTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
const lockTime = useRef(0);
Expand All @@ -31,6 +64,10 @@ export function usePagination({ bookKey, viewRef, containerRef }: UsePaginationO

if (view.renderer?.scrolled) return;

if (isFixedLayout && scrollFixedLayoutPage(view, deltaY, deltaX)) {
return;
}

const absDY = Math.abs(deltaY);
const absDX = Math.abs(deltaX || 0);
if (absDY < 2 && absDX < 2) return;
Expand Down Expand Up @@ -69,7 +106,7 @@ export function usePagination({ bookKey, viewRef, containerRef }: UsePaginationO
wheelLocked.current = false;
}, WHEEL_IDLE_MS);
},
[viewRef],
[isFixedLayout, viewRef],
);

useEffect(() => {
Expand Down