import { useCallback } from 'react' import config from '../../../config' import loglevel from 'loglevel' const logger = loglevel.getLogger('useTableScroll') logger.setLevel(config.logLevel) export const useTableScroll = ({ lazyLoading, hasMore, hasPrevious, currentLoadedPageNumber, loadingPages, createSkeletonData, fetchData, setCurrentLoadedPageNumber, setLazyLoading, setPages, setLoadedPages, loadedPages }) => { const handleScroll = useCallback( (e) => { const { target } = e const scrollHeight = target.scrollHeight const scrollTop = target.scrollTop const clientHeight = target.clientHeight // Load more data when scrolling down if ( scrollHeight - scrollTop - clientHeight < 100 && !lazyLoading && hasMore ) { logger.debug(loadedPages) const lowestPage = Math.max(...loadedPages) const nextPage = lowestPage + 1 if (!loadingPages.has(nextPage)) { setLazyLoading(true) setCurrentLoadedPageNumber(nextPage) setPages((prev) => { const filteredPages = prev.map((page) => ({ ...page, items: page.items.filter((item) => !item.isSkeleton) })) const relevantPages = filteredPages.slice(-2) logger.debug('Pages after scroll down:', { current: currentLoadedPageNumber, next: nextPage, keeping: relevantPages.map((p) => p.pageNum) }) return [ ...relevantPages, { pageNum: nextPage, items: createSkeletonData() } ] }) // Adjust scroll position to center the new content setTimeout(() => { const newScrollTop = (target.scrollHeight - clientHeight) / 2 target.scrollTo({ top: newScrollTop }) }, 0) fetchData(nextPage, true) } } // Load previous data when scrolling up if ( scrollTop < 100 && !lazyLoading && hasPrevious && currentLoadedPageNumber > 1 ) { const lowestPage = Math.min(...loadedPages) const prevPage = lowestPage - 1 if (!loadingPages.has(prevPage)) { setLazyLoading(true) setCurrentLoadedPageNumber(prevPage) setPages((prev) => { const relevantPages = filteredPages.slice(0, 1) const filteredPages = prev.map((page) => ({ ...page, items: page.items.filter((item) => !item.isSkeleton) })) logger.debug('Pages after scroll up:', { current: currentLoadedPageNumber, prev: prevPage, keeping: relevantPages.map((p) => p.pageNum) }) return [ { pageNum: prevPage, items: createSkeletonData() }, ...relevantPages ] }) setLoadedPages((prev) => { const relevantPages = prev.slice(0, 1) return [prevPage, ...relevantPages] }) // Adjust scroll position to center the new content setTimeout(() => { const newScrollTop = (target.scrollHeight - clientHeight) / 2 target.scrollTo({ top: newScrollTop }) }, 0) fetchData(prevPage, false, true) } } }, [ lazyLoading, hasMore, hasPrevious, currentLoadedPageNumber, loadingPages, createSkeletonData, fetchData, setCurrentLoadedPageNumber, setLazyLoading, setPages, setLoadedPages, loadedPages ] ) return { handleScroll } }