import { type SystemStyleObject, Box, EmptyState, HStack, ScrollArea, Separator, Spinner, Text, VStack } from '@chakra-ui/react'; import type {UseInfiniteQueryResult} from '@tanstack/react-query'; import { useVirtualizer } from "@tanstack/react-virtual"; import React, { type ComponentProps, useCallback, useMemo } from "react"; import { LuCaptionsOff } from "react-icons/lu"; import { ActivityCollapsible } from '../ActivityDetail.js'; import { type ActivityLogProps, generateFlatItems, GroupHeader, isGroupInfo } from './ListParts.js'; const itemContainerStyle: React.ComponentProps<"div"> = { style: { position: "absolute", top: 0, left: 0, width: "100%", paddingBottom: 4, } }; const containerStyle: React.ComponentProps<"div"> = { style: { //width: "100%", position: "relative", } } const scrollShadowCss: SystemStyleObject = { "--scroll-shadow-size": "4rem", maskImage: "linear-gradient(#000, #000)", "&[data-overflow-y]": { maskImage: "linear-gradient(#000,#000,transparent 0,#000 var(--scroll-shadow-size),#000 calc(100% - var(--scroll-shadow-size)),transparent)", "&[data-at-top]": { maskImage: "linear-gradient(180deg,#000 calc(100% - var(--scroll-shadow-size)),transparent)", }, "&[data-at-bottom]": { maskImage: "linear-gradient(0deg,#000 calc(100% - var(--scroll-shadow-size)),transparent)", }, }, }; export const VirtualizedListDynamic = (props: ActivityLogProps & Pick) => { const { data = [], sortBy, live = false, hasNextPage, isFetchingNextPage, fetchNextPage, total, } = props; const items = useMemo(() => { return generateFlatItems(data); }, [data]); const getItemKey = useCallback((index) => { return items[index] !== undefined ? items[index].uid : index; },[items]); const parentRef = React.useRef(null) // The virtualizer const virtualizer = useVirtualizer({ count: items.length + 1, getScrollElement: () => parentRef.current, getItemKey: getItemKey, estimateSize: () => 85, directDomUpdates: true, //directDomUpdatesMode: 'position', overscan: 4, //debug: true }); React.useEffect(() => { const [lastItem] = [...virtualizer.getVirtualItems()].reverse() if (!lastItem) { return } //console.log(`Last Item Index ${lastItem.index} | Items ${items.length} | Has Next Page? ${hasNextPage} | Is Fetching Next? ${isFetchingNextPage}`); if ( lastItem.index >= items.length - 1 && hasNextPage && !isFetchingNextPage ) { console.log('Invoke next fetch'); fetchNextPage() } }, [ hasNextPage, fetchNextPage, items.length, isFetchingNextPage, virtualizer.getVirtualItems(), ]) // doesn't seem like i need this for height to work correctly? // // const containerStyleProps = useMemo( // (): React.ComponentProps<"div"> => ({ // style: { // height: `${virtualizer.getTotalSize()}px`, // width: "100%", // position: "relative", // }, // }), // [virtualizer], // ) // const itemContainerStyleProps = useCallback( // (item: VirtualItem): React.ComponentProps<"div"> => ({ // style: { // position: "absolute", // top: 0, // left: 0, // width: "100%", // paddingBottom: 4, // height: `${item.size}px`, // transform: `translateY(${item.start}px)`, // }, // }), // [], // ) return ( {total !== undefined ? {total} Plays Total : null} {virtualizer.getVirtualItems().map((virtualItem) => { const item = items[virtualItem.index] const isLoaderRow = virtualItem.index > items.length - 1 return ( {isLoaderRow ? hasNextPage ? ( Loading... ) : : } ) })} ); } const ItemContainer = (props: ComponentProps & ComponentProps) => { if(isGroupInfo(props.data)) { return } return } export const NoPlayResults = (props: {type: 'empty' | 'additional'}) => { return ( No{props.type === 'additional' ? ' more ' :' '}Plays found {props.type === 'additional' ? ( 'There are no more Plays for this search.' ) : 'No Plays were found for this search. Try broadening the filters.' } ); }