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[]; children: (item: any, index: number) => React.ReactNode; onSeenLastItem?: (item: QortalMetadata)=> void; } 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) } }, []); return (
{rowVirtualizer.getVirtualItems().map((virtualRow) => { const index = virtualRow.index; const item = list[index]; return (
onSeenLastItemFunc(item)} > {typeof children === "function" ? children(item, index) : null}
); })}
); }; interface MessageWrapperProps { onSeen: () => void; isLast: boolean; children: ReactNode; } export const MessageWrapper: React.FC = ({ onSeen, isLast, children, }) => { if (isLast) { return ( {children} ); } return <>{children}; }; interface WatchComponentProps { onSeen: () => void; isLast: boolean; children: ReactNode; } const WatchComponent: React.FC = ({ onSeen, isLast, children, }) => { const { ref, inView } = useInView({ threshold: 0.7, triggerOnce: true, // Ensure it only triggers once per mount }); const hasBeenTriggered = useRef(false); // Prevent multiple triggers useEffect(() => { if (inView && isLast && onSeen && !hasBeenTriggered.current) { onSeen(); hasBeenTriggered.current = true; // Mark as triggered } }, [inView, isLast, onSeen]); return (
{children}
); };