diff --git a/src/app/tools/tankopedia/components/SkeletonTankCard.tsx b/src/app/tools/tankopedia/components/SkeletonTankCard.tsx
index 5aaff521e..a955951fc 100644
--- a/src/app/tools/tankopedia/components/SkeletonTankCard.tsx
+++ b/src/app/tools/tankopedia/components/SkeletonTankCard.tsx
@@ -1,10 +1,25 @@
import { Flex, Skeleton } from '@radix-ui/themes';
+import { memo, useRef } from 'react';
+import { useIntersection } from '../../../../hooks/useIntersection';
-export function SkeletonTankCard() {
- return (
-
-
-
-
- );
+interface SkeletonTankCardProps {
+ onIntersection?: () => void;
}
+
+export const SkeletonTankCard = memo(
+ ({ onIntersection }: SkeletonTankCardProps) => {
+ const card = useRef(null);
+
+ useIntersection(() => onIntersection?.(), card, {
+ disabled: onIntersection === undefined,
+ });
+
+ return (
+
+
+
+
+ );
+ },
+ () => true,
+);
diff --git a/src/app/tools/tankopedia/components/TankSearch/index.tsx b/src/app/tools/tankopedia/components/TankSearch/index.tsx
index 964d50c9a..5d14205be 100644
--- a/src/app/tools/tankopedia/components/TankSearch/index.tsx
+++ b/src/app/tools/tankopedia/components/TankSearch/index.tsx
@@ -1,7 +1,9 @@
+'use client';
+
import { Callout, Flex, FlexProps, Link, Text } from '@radix-ui/themes';
import { go } from 'fuzzysort';
import { times } from 'lodash';
-import { memo, use, useMemo } from 'react';
+import { memo, use, useEffect, useMemo, useState } from 'react';
import { AdMidSectionResponsive } from '../../../../../components/AdMidSectionResponsive';
import { ExperimentIcon } from '../../../../../components/ExperimentIcon';
import { TANK_CLASSES } from '../../../../../components/Tanks/components/Item/constants';
@@ -40,6 +42,9 @@ type TankSearchProps = Omit & {
onSelectAll?: (tanks: TankDefinition[]) => void;
};
+const PREVIEW_COUNT = 25;
+const DEFAULT_LOADED_CARDS = 75;
+
export const TankSearch = memo(
({ compact, onSelect, onSelectAll, ...props }) => {
const exempt = useAdExempt();
@@ -50,7 +55,7 @@ export const TankSearch = memo(
const awaitedTankNames = use(tankNames);
const filters = TankFilters.use();
const sort = TankopediaSort.use();
- const tanks = useMemo(() => {
+ const tanksFiltered = useMemo(() => {
if (filters.search === undefined) {
const filtered = awaitedTanksDefinitionsArray.filter((tank) =>
filterTank(filters, tank),
@@ -379,6 +384,12 @@ export const TankSearch = memo(
return searchedTanks;
}
}, [filters]);
+ const [loadedRows, setLoadedRows] = useState(DEFAULT_LOADED_CARDS);
+ const tanks = tanksFiltered.slice(0, loadedRows);
+
+ useEffect(() => {
+ setLoadedRows(DEFAULT_LOADED_CARDS);
+ }, [filters, sort]);
return (
@@ -447,6 +458,22 @@ export const TankSearch = memo(
)}
>
))}
+
+ {times(
+ Math.min(PREVIEW_COUNT, tanksFiltered.length - loadedRows),
+ (index) => {
+ return (
+ {
+ setLoadedRows((state) =>
+ Math.min(state + 2, tanksFiltered.length),
+ );
+ }}
+ />
+ );
+ },
+ )}
)}
diff --git a/src/app/tools/tankopedia/page.tsx b/src/app/tools/tankopedia/page.tsx
index 827fa169a..92158b251 100644
--- a/src/app/tools/tankopedia/page.tsx
+++ b/src/app/tools/tankopedia/page.tsx
@@ -1,19 +1,12 @@
-'use client';
-
-import { AdMidSectionResponsive } from '../../../components/AdMidSectionResponsive';
import PageWrapper from '../../../components/PageWrapper';
-import { useAdExempt } from '../../../hooks/useAdExempt';
import * as TankFilters from '../../../stores/tankFilters';
import { TankSearch } from './components/TankSearch';
export default function Page() {
- const exempt = useAdExempt();
-
return (
- {!exempt && }
);