Fix infinite scroll intersection info calculation

Scrollbars need to be considered since they decrease the available viewport size in which the element can be visible
This commit is contained in:
schroda
2025-02-10 22:27:28 +01:00
parent eb7397e639
commit a45338647e
3 changed files with 24 additions and 5 deletions

View File

@@ -416,6 +416,8 @@ const BaseReaderChapterViewer = ({
isPreviousChapterVisible={isPreviousChapterVisible}
isNextChapterVisible={isNextChapterVisible}
imageWrapper={pagerRef.current}
scrollbarXSize={scrollbarXSize}
scrollbarYSize={scrollbarYSize}
/>
)}
{showPreviousTransitionPage && (

View File

@@ -9,7 +9,7 @@
import { memo } from 'react';
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
import { useReaderInfiniteScrollUpdateChapter } from '@/modules/reader/hooks/useReaderInfiniteScrollUpdateChapter.ts';
import { ReadingDirection, ReadingMode } from '@/modules/reader/types/Reader.types.ts';
import { ReadingDirection, ReadingMode, TReaderScrollbarContext } from '@/modules/reader/types/Reader.types.ts';
import { ReaderControls } from '@/modules/reader/services/ReaderControls.ts';
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
@@ -24,7 +24,9 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
isNextChapterVisible,
imageWrapper,
openChapter,
}: {
scrollbarXSize,
scrollbarYSize,
}: Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'> & {
readingMode: ReadingMode;
readingDirection: ReadingDirection;
chapterId: ChapterIdInfo['id'];
@@ -46,6 +48,8 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
readingDirection,
openChapter,
imageWrapper,
scrollbarXSize,
scrollbarYSize,
);
useReaderInfiniteScrollUpdateChapter(
'last',
@@ -57,6 +61,8 @@ const BaseReaderInfiniteScrollUpdateChapter = ({
readingDirection,
openChapter,
imageWrapper,
scrollbarXSize,
scrollbarYSize,
);
return null;

View File

@@ -36,18 +36,23 @@ const OPEN_CHAPTER_INTERSECTION_RATIO = 0;
const getElementIntersectionInfo = (
readingDirection: ReadingDirection,
{ top, right, bottom, left }: DOMRect,
scrollbarXSize: number,
scrollbarYSize: number,
): ElementIntersectionInfo => {
const themeDirectionOfReadingDirection = READING_DIRECTION_TO_THEME_DIRECTION[readingDirection];
const startOfViewportHorizontal = getOptionForDirection(0, window.innerWidth, themeDirectionOfReadingDirection);
const endOfViewportHorizontal = getOptionForDirection(window.innerWidth, 0, themeDirectionOfReadingDirection);
const viewportWidth = window.innerWidth - scrollbarYSize;
const viewportHeight = window.innerHeight - scrollbarXSize;
const startOfViewportHorizontal = getOptionForDirection(0, viewportWidth, themeDirectionOfReadingDirection);
const endOfViewportHorizontal = getOptionForDirection(viewportWidth, 0, themeDirectionOfReadingDirection);
const startOfElementHorizontal = getOptionForDirection(left, right, themeDirectionOfReadingDirection);
const endOfElementHorizontal = getOptionForDirection(right, left, themeDirectionOfReadingDirection);
return {
[ReadingMode.CONTINUOUS_VERTICAL]: {
start: bottom >= window.innerHeight,
start: bottom >= viewportHeight,
end: top < 0,
},
[ReadingMode.CONTINUOUS_HORIZONTAL]: {
@@ -188,6 +193,8 @@ export const useReaderInfiniteScrollUpdateChapter = (
readingDirection: ReadingDirection,
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>,
image: HTMLElement | null,
scrollbarXSize: number,
scrollbarYSize: number,
) => {
useIntersectionObserver(
image,
@@ -202,6 +209,8 @@ export const useReaderInfiniteScrollUpdateChapter = (
const elementIntersectionInfo = getElementIntersectionInfo(
readingDirection,
entry.target.getBoundingClientRect(),
scrollbarXSize,
scrollbarYSize,
);
const { start: isStartIntersecting, end: isEndIntersecting } = getElementIntersection(
elementIntersectionInfo,
@@ -239,6 +248,8 @@ export const useReaderInfiniteScrollUpdateChapter = (
readingMode,
readingDirection,
openChapter,
scrollbarXSize,
scrollbarYSize,
],
),
useMemo(