diff --git a/src/app/tools/tank-performance/components/RowLoader.tsx b/src/app/tools/tank-performance/components/RowLoader.tsx index e35b0c295..09ebbab69 100644 --- a/src/app/tools/tank-performance/components/RowLoader.tsx +++ b/src/app/tools/tank-performance/components/RowLoader.tsx @@ -1,10 +1,26 @@ import { Skeleton, Table } from '@radix-ui/themes'; import { times } from 'lodash'; +import { useEffect, useRef } from 'react'; import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort'; -export function RowLoader() { +interface RowLoaderProps { + onIntersection?: () => void; +} + +export function RowLoader({ onIntersection }: RowLoaderProps) { + const row = useRef(null); + + useEffect(() => { + if (!onIntersection || !row.current) return; + + const observer = new IntersectionObserver(onIntersection); + observer.observe(row.current); + + return () => observer.disconnect(); + }, []); + return ( - + diff --git a/src/app/tools/tank-performance/components/Tanks.tsx b/src/app/tools/tank-performance/components/Tanks.tsx index 293874b36..02a82989b 100644 --- a/src/app/tools/tank-performance/components/Tanks.tsx +++ b/src/app/tools/tank-performance/components/Tanks.tsx @@ -1,7 +1,8 @@ 'use client'; import { Table } from '@radix-ui/themes'; -import { Suspense, use, useMemo } from 'react'; +import { times } from 'lodash'; +import { Suspense, use, useEffect, useMemo, useState } from 'react'; import { averageDefinitionsArray } from '../../../../core/blitzkit/averageDefinitions'; import { filterTank } from '../../../../core/blitzkit/filterTank'; import { tankDefinitions } from '../../../../core/blitzkit/tankDefinitions'; @@ -10,6 +11,9 @@ import { useTankPerformanceSort } from '../../../../stores/tankPerformanceSort'; import { RowLoader } from './RowLoader'; import { TankRow } from './TankRow'; +const PREVIEW_COUNT = 10; +const DEFAULT_LOADED_ROWS = 25; + export function Tanks() { const awaitedTankDefinitions = use(tankDefinitions); const awaitedAverageDefinitionsArray = use(averageDefinitionsArray); @@ -108,11 +112,16 @@ export function Tanks() { return tanksSorted.filter((tank) => filterTank(filters, awaitedTankDefinitions[tank.id]), ); - }, [filters, tanksSorted, sort]); + }, [filters, sort]); + const [loadedRows, setLoadedRows] = useState(DEFAULT_LOADED_ROWS); + + useEffect(() => { + setLoadedRows(DEFAULT_LOADED_ROWS); + }, [filters, sort]); return ( - {tanks.map((averages) => { + {tanks.slice(0, loadedRows).map((averages) => { const tank = awaitedTankDefinitions[averages.id]; return ( }> @@ -120,6 +129,24 @@ export function Tanks() { ); })} + + {times(Math.min(PREVIEW_COUNT, tanks.length - loadedRows), (index) => { + return ( + { + console.log('Intersected'); + setLoadedRows((state) => + Math.min(state + PREVIEW_COUNT, tanks.length), + ); + } + : undefined + } + /> + ); + })} ); }