feat: fast observers

This commit is contained in:
TrèsAbhi committed 2024-07-06 20:32:41 -05:00
1 parent b965893bfc
commit 33c67b9416
2 files changed
+48 -5

No files matched your search

@@ -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<HTMLTableRowElement>(null);
useEffect(() => {
if (!onIntersection || !row.current) return;
const observer = new IntersectionObserver(onIntersection);
observer.observe(row.current);
return () => observer.disconnect();
}, []);
return (
<Table.Row>
<Table.Row ref={row}>
<Table.RowHeaderCell align="center">
<Skeleton height="100%" width="128px" />
</Table.RowHeaderCell>
@@ -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 (
<Table.Body>
{tanks.map((averages) => {
{tanks.slice(0, loadedRows).map((averages) => {
const tank = awaitedTankDefinitions[averages.id];
return (
<Suspense key={tank.id} fallback={<RowLoader />}>
@@ -120,6 +129,24 @@ export function Tanks() {
</Suspense>
);
})}
{times(Math.min(PREVIEW_COUNT, tanks.length - loadedRows), (index) => {
return (
<RowLoader
key={index}
onIntersection={
index === 0
? () => {
console.log('Intersected');
setLoadedRows((state) =>
Math.min(state + PREVIEW_COUNT, tanks.length),
);
}
: undefined
}
/>
);
})}
</Table.Body>
);
}