Use new ResizeObserver hook
This commit is contained in:
@@ -6,7 +6,16 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import React, { ForwardedRef, forwardRef, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||
import React, {
|
||||
ForwardedRef,
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import Grid, { GridTypeMap } from '@mui/material/Grid';
|
||||
import Box from '@mui/material/Box';
|
||||
import { GridItemProps, GridStateSnapshot, VirtuosoGrid } from 'react-virtuoso';
|
||||
@@ -22,6 +31,7 @@ import { DEFAULT_FULL_FAB_HEIGHT } from '@/components/util/StyledFab.tsx';
|
||||
import { AppStorage } from '@/util/AppStorage.ts';
|
||||
import { MangaCardProps } from '@/components/manga/MangaCard.types.tsx';
|
||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
||||
|
||||
const GridContainer = React.forwardRef<HTMLDivElement, GridTypeMap['props']>(({ children, ...props }, ref) => (
|
||||
<Grid {...props} ref={ref} container sx={{ paddingLeft: '5px', paddingRight: '13px' }}>
|
||||
@@ -310,39 +320,32 @@ export const MangaGrid: React.FC<IMangaGridProps> = ({
|
||||
return () => window.removeEventListener('resize', onResize);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!gridRef.current) {
|
||||
return () => {};
|
||||
}
|
||||
useResizeObserver(
|
||||
gridRef,
|
||||
useCallback(
|
||||
(entries, resizeObserver) => {
|
||||
const gridHeight = entries[0].target.clientHeight;
|
||||
const isScrollbarVisible = gridHeight > document.documentElement.clientHeight;
|
||||
|
||||
if (gridRef.current.offsetHeight > document.documentElement.clientHeight) {
|
||||
return () => {};
|
||||
}
|
||||
if (isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
const gridHeight = entries[0].target.clientHeight;
|
||||
const isScrollbarVisible = gridHeight > document.documentElement.clientHeight;
|
||||
if (!gridHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return;
|
||||
}
|
||||
if (isScrollbarVisible) {
|
||||
resizeObserver.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gridHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isScrollbarVisible) {
|
||||
loadMore();
|
||||
resizeObserver.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
loadMore();
|
||||
resizeObserver.disconnect();
|
||||
});
|
||||
resizeObserver.observe(gridRef.current);
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, [loadMore, isLoading]);
|
||||
},
|
||||
[gridRef, loadMore, isLoading],
|
||||
),
|
||||
);
|
||||
|
||||
const hasNoItems = !isLoading && mangas.length === 0;
|
||||
if (hasNoItems) {
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { MouseEvent as ReactMouseEvent, useEffect, useLayoutEffect, useRef } from 'react';
|
||||
import { MouseEvent as ReactMouseEvent, useCallback, useEffect, useRef } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import { IReaderProps } from '@/typings';
|
||||
import { Page } from '@/components/reader/Page';
|
||||
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
||||
|
||||
const findCurrentPageIndex = (wrapper: HTMLDivElement): number => {
|
||||
for (let i = 0; i < wrapper.children.length; i++) {
|
||||
@@ -107,24 +108,21 @@ export function HorizontalPager(props: IReaderProps) {
|
||||
}
|
||||
};
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const initialPageElement = pagesRef.current[initialPage];
|
||||
if (!initialPageElement) {
|
||||
return () => {};
|
||||
}
|
||||
useResizeObserver(
|
||||
pagesRef.current[initialPage],
|
||||
useCallback(
|
||||
(_, resizeObserver) => {
|
||||
const initialPageElement = pagesRef.current[initialPage];
|
||||
if (!initialPageElement?.offsetHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
if (!initialPageElement.offsetHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
initialPageElement.scrollIntoView({ inline: 'center' });
|
||||
resizeObserver.disconnect();
|
||||
});
|
||||
resizeObserver.observe(initialPageElement);
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, [initialPage]);
|
||||
initialPageElement.scrollIntoView({ inline: 'center' });
|
||||
resizeObserver.disconnect();
|
||||
},
|
||||
[pagesRef.current[initialPage], initialPage],
|
||||
),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
selfRef.current?.addEventListener('mousedown', dragControl);
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useLayoutEffect, useRef } from 'react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import { IReaderProps } from '@/typings';
|
||||
import { Page } from '@/components/reader/Page';
|
||||
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
||||
|
||||
const findCurrentPageIndex = (wrapper: HTMLDivElement): number => {
|
||||
for (let i = 0; i < wrapper.children.length; i++) {
|
||||
@@ -165,24 +166,21 @@ export function VerticalPager(props: IReaderProps) {
|
||||
};
|
||||
}, [go]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const initialPageElement = pagesRef.current[initialPage];
|
||||
if (!initialPageElement) {
|
||||
return () => {};
|
||||
}
|
||||
useResizeObserver(
|
||||
pagesRef.current[initialPage],
|
||||
useCallback(
|
||||
(_, resizeObserver) => {
|
||||
const initialPageElement = pagesRef.current[initialPage];
|
||||
if (!initialPageElement?.offsetHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
if (!initialPageElement.offsetHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
initialPageElement.scrollIntoView();
|
||||
resizeObserver.disconnect();
|
||||
});
|
||||
resizeObserver.observe(initialPageElement);
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, [initialPage]);
|
||||
initialPageElement.scrollIntoView();
|
||||
resizeObserver.disconnect();
|
||||
},
|
||||
[pagesRef.current[initialPage], initialPage],
|
||||
),
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
||||
@@ -6,17 +6,28 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { RefObject, useLayoutEffect } from 'react';
|
||||
import { RefObject, useLayoutEffect, useState } from 'react';
|
||||
|
||||
export const useResizeObserver = (
|
||||
ref: RefObject<HTMLElement> | HTMLElement | undefined,
|
||||
callback: ResizeObserverCallback,
|
||||
): (() => void) => {
|
||||
const [disconnect, setDisconnect] = useState<() => void>(() => {});
|
||||
|
||||
export const useResizeObserver = (ref: RefObject<HTMLElement>, callback: ResizeObserverCallback) => {
|
||||
useLayoutEffect(() => {
|
||||
if (!ref.current) {
|
||||
const element = ref instanceof HTMLElement ? ref : ref?.current;
|
||||
|
||||
if (!element) {
|
||||
return () => {};
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(callback);
|
||||
resizeObserver.observe(ref.current);
|
||||
resizeObserver.observe(element);
|
||||
|
||||
setDisconnect(() => () => resizeObserver.disconnect());
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, [ref, callback]);
|
||||
|
||||
return disconnect;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user