diff --git a/package-lock.json b/package-lock.json index 6ea2e3a..51b2e40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@mui/material": "^6.4.7", "@tanstack/react-virtual": "^3.13.2", "react": "^19.0.0", + "react-intersection-observer": "^9.16.0", "zustand": "^4.3.2" }, "devDependencies": { @@ -2121,6 +2122,20 @@ "react": "^19.0.0" } }, + "node_modules/react-intersection-observer": { + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz", + "integrity": "sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA==", + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", diff --git a/package.json b/package.json index 72851ae..24d10c2 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@mui/material": "^6.4.7", "@tanstack/react-virtual": "^3.13.2", "react": "^19.0.0", + "react-intersection-observer": "^9.16.0", "zustand": "^4.3.2" }, "devDependencies": { diff --git a/src/common/VirtualizedList.tsx b/src/common/VirtualizedList.tsx index 1324683..c66d63b 100644 --- a/src/common/VirtualizedList.tsx +++ b/src/common/VirtualizedList.tsx @@ -1,92 +1,176 @@ -import React, { CSSProperties, useCallback, useRef } from 'react' +import React, { + CSSProperties, + ReactNode, + useCallback, + useEffect, + useRef, +} from "react"; import { useVirtualizer } from "@tanstack/react-virtual"; +import { useInView } from "react-intersection-observer"; +import { QortalMetadata } from "../types/interfaces/resources"; interface PropsVirtualizedList { - list: any[] + list: any[]; children: (item: any, index: number) => React.ReactNode; + onSeenLastItem?: (item: QortalMetadata)=> void; } -export const VirtualizedList = ({list, children}: PropsVirtualizedList) => { - const parentRef = useRef(null); +export const VirtualizedList = ({ list, children, onSeenLastItem }: PropsVirtualizedList) => { + const parentRef = useRef(null); + + const rowVirtualizer = useVirtualizer({ + count: list.length, + getItemKey: useCallback( + (index: number) => + list[index]?.name && list[index]?.name + ? `${list[index].name}-${list[index].identifier}` + : list[index]?.id, + [list] + ), + getScrollElement: () => parentRef.current, + estimateSize: () => 80, // Provide an estimated height of items, adjust this as needed + overscan: 10, // Number of items to render outside the visible area to improve smoothness + }); + + const onSeenLastItemFunc = useCallback((lastItem: QortalMetadata) => { + if(onSeenLastItem){ + onSeenLastItem(lastItem) + } - const rowVirtualizer = useVirtualizer({ - count: list.length, - getItemKey: useCallback((index: number) => (list[index]?.name && list[index]?.name) ?`${list[index].name}-${list[index].identifier}`: list[index]?.id, [list]), - getScrollElement: () => parentRef.current, - estimateSize: () => 80, // Provide an estimated height of items, adjust this as needed - overscan: 10, // Number of items to render outside the visible area to improve smoothness - }); + }, []); return ( -