mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: fast observers
This commit is contained in:
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 { Skeleton, Table } from '@radix-ui/themes';
|
||||||
import { times } from 'lodash';
|
import { times } from 'lodash';
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort';
|
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 (
|
return (
|
||||||
<Table.Row>
|
<Table.Row ref={row}>
|
||||||
<Table.RowHeaderCell align="center">
|
<Table.RowHeaderCell align="center">
|
||||||
<Skeleton height="100%" width="128px" />
|
<Skeleton height="100%" width="128px" />
|
||||||
</Table.RowHeaderCell>
|
</Table.RowHeaderCell>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Table } from '@radix-ui/themes';
|
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 { averageDefinitionsArray } from '../../../../core/blitzkit/averageDefinitions';
|
||||||
import { filterTank } from '../../../../core/blitzkit/filterTank';
|
import { filterTank } from '../../../../core/blitzkit/filterTank';
|
||||||
import { tankDefinitions } from '../../../../core/blitzkit/tankDefinitions';
|
import { tankDefinitions } from '../../../../core/blitzkit/tankDefinitions';
|
||||||
@@ -10,6 +11,9 @@ import { useTankPerformanceSort } from '../../../../stores/tankPerformanceSort';
|
|||||||
import { RowLoader } from './RowLoader';
|
import { RowLoader } from './RowLoader';
|
||||||
import { TankRow } from './TankRow';
|
import { TankRow } from './TankRow';
|
||||||
|
|
||||||
|
const PREVIEW_COUNT = 10;
|
||||||
|
const DEFAULT_LOADED_ROWS = 25;
|
||||||
|
|
||||||
export function Tanks() {
|
export function Tanks() {
|
||||||
const awaitedTankDefinitions = use(tankDefinitions);
|
const awaitedTankDefinitions = use(tankDefinitions);
|
||||||
const awaitedAverageDefinitionsArray = use(averageDefinitionsArray);
|
const awaitedAverageDefinitionsArray = use(averageDefinitionsArray);
|
||||||
@@ -108,11 +112,16 @@ export function Tanks() {
|
|||||||
return tanksSorted.filter((tank) =>
|
return tanksSorted.filter((tank) =>
|
||||||
filterTank(filters, awaitedTankDefinitions[tank.id]),
|
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 (
|
return (
|
||||||
<Table.Body>
|
<Table.Body>
|
||||||
{tanks.map((averages) => {
|
{tanks.slice(0, loadedRows).map((averages) => {
|
||||||
const tank = awaitedTankDefinitions[averages.id];
|
const tank = awaitedTankDefinitions[averages.id];
|
||||||
return (
|
return (
|
||||||
<Suspense key={tank.id} fallback={<RowLoader />}>
|
<Suspense key={tank.id} fallback={<RowLoader />}>
|
||||||
@@ -120,6 +129,24 @@ export function Tanks() {
|
|||||||
</Suspense>
|
</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>
|
</Table.Body>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user