mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: complete sort labels
This commit is contained in:
1 parent
77105b514e
commit
8bcd74262c
10 files changed
+200
-177
No files matched your search
@@ -343,7 +343,7 @@ export function Characteristics() {
|
||||
{stats.dispersion}
|
||||
</InfoWithDelta>
|
||||
<InfoWithDelta
|
||||
prefix="+ "
|
||||
prefix="+"
|
||||
decimals={3}
|
||||
indent
|
||||
name="Moving"
|
||||
@@ -353,7 +353,7 @@ export function Characteristics() {
|
||||
</InfoWithDelta>
|
||||
<InfoWithDelta
|
||||
decimals={3}
|
||||
prefix="+ "
|
||||
prefix="+"
|
||||
indent
|
||||
name="Hull traversing"
|
||||
deltaType="lowerIsBetter"
|
||||
@@ -362,7 +362,7 @@ export function Characteristics() {
|
||||
</InfoWithDelta>
|
||||
<InfoWithDelta
|
||||
decimals={3}
|
||||
prefix="+ "
|
||||
prefix="+"
|
||||
indent
|
||||
name="Turret traversing"
|
||||
deltaType="lowerIsBetter"
|
||||
@@ -371,7 +371,7 @@ export function Characteristics() {
|
||||
</InfoWithDelta>
|
||||
<InfoWithDelta
|
||||
decimals={3}
|
||||
prefix="+ "
|
||||
prefix="+"
|
||||
indent
|
||||
name="After shooting"
|
||||
deltaType="lowerIsBetter"
|
||||
|
||||
@@ -42,7 +42,7 @@ export function FilterControl() {
|
||||
highContrast
|
||||
onClick={() =>
|
||||
mutateTankopediaFilters((draft) => {
|
||||
draft.tier = tier;
|
||||
draft.tier = draft.tier === tier ? undefined : tier;
|
||||
})
|
||||
}
|
||||
>
|
||||
@@ -65,7 +65,7 @@ export function FilterControl() {
|
||||
highContrast
|
||||
onClick={() =>
|
||||
mutateTankopediaFilters((draft) => {
|
||||
draft.tier = tier;
|
||||
draft.tier = draft.tier === tier ? undefined : tier;
|
||||
})
|
||||
}
|
||||
>
|
||||
|
||||
@@ -3,7 +3,9 @@ import { go } from 'fuzzysort';
|
||||
import { times } from 'lodash';
|
||||
import { memo, use, useMemo } from 'react';
|
||||
import { ExperimentIcon } from '../../../../components/ExperimentIcon';
|
||||
import { TANK_CLASSES } from '../../../../components/Tanks/components/Item/constants';
|
||||
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
|
||||
import { gameDefinitions } from '../../../../core/blitzkit/gameDefinitions';
|
||||
import { modelDefinitions } from '../../../../core/blitzkit/modelDefinitions';
|
||||
import { normalizeBoundingBox } from '../../../../core/blitzkit/normalizeBoundingBox';
|
||||
import { resolveDpm } from '../../../../core/blitzkit/resolveDpm';
|
||||
@@ -14,6 +16,7 @@ import {
|
||||
tankNames,
|
||||
tanksDefinitionsArray,
|
||||
} from '../../../../core/blitzkit/tankDefinitions';
|
||||
import { tankopediaFilterTank } from '../../../../core/blitzkit/tankopediaFilterTank';
|
||||
import { unionBoundingBox } from '../../../../core/blitzkit/unionBoundingBox';
|
||||
import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
|
||||
import { FilterControl } from './FilterControl';
|
||||
@@ -22,35 +25,41 @@ import { SearchBar } from './SearchBar';
|
||||
import { SkeletonTankCard } from './SkeletonTankCard';
|
||||
import { TankCard } from './TankCard';
|
||||
import { TankCardWrapper } from './TankCardWrapper';
|
||||
import { TierCard } from './TierCard';
|
||||
import { treeTypeOrder } from './TankSearch/constants';
|
||||
|
||||
export const Results = memo(() => {
|
||||
const awaitedGameDefinitions = use(gameDefinitions);
|
||||
const awaitedModelDefinitions = use(modelDefinitions);
|
||||
const awaitedTankDefinitions = use(tankDefinitions);
|
||||
const awaitedTanksDefinitionsArray = use(tanksDefinitionsArray);
|
||||
const awaitedTankNames = use(tankNames);
|
||||
const testing = useTankopediaFilters((state) => state.testing);
|
||||
const search = useTankopediaFilters((state) => state.search);
|
||||
const tier = useTankopediaFilters((state) => state.tier);
|
||||
const sort = useTankopediaFilters((state) => state.sort);
|
||||
const searching = useTankopediaFilters((state) => state.searching);
|
||||
const searchedTanks = useMemo(() => {
|
||||
if (search !== undefined) {
|
||||
const searchedRaw = go(search, awaitedTankNames, {
|
||||
key: 'combined',
|
||||
limit: 25,
|
||||
});
|
||||
const searchedTanks = searchedRaw.map(
|
||||
(result) => awaitedTankDefinitions[result.obj.id],
|
||||
const filters = useTankopediaFilters();
|
||||
const tanks = useMemo(() => {
|
||||
if (filters.search === undefined) {
|
||||
const filtered = awaitedTanksDefinitionsArray.filter((tank) =>
|
||||
tankopediaFilterTank(filters, tank),
|
||||
);
|
||||
return searchedTanks;
|
||||
}
|
||||
|
||||
if (sort.by !== 'meta.tier') {
|
||||
const filtered = awaitedTanksDefinitionsArray;
|
||||
let sorted: TankDefinition[];
|
||||
|
||||
switch (sort.by) {
|
||||
switch (filters.sort.by) {
|
||||
case 'meta.none':
|
||||
sorted = filtered
|
||||
.sort(
|
||||
(a, b) =>
|
||||
treeTypeOrder.indexOf(b.treeType) -
|
||||
treeTypeOrder.indexOf(a.treeType),
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
TANK_CLASSES.indexOf(b.class) - TANK_CLASSES.indexOf(a.class),
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
awaitedGameDefinitions.nations.indexOf(b.nation) -
|
||||
awaitedGameDefinitions.nations.indexOf(a.nation),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'survivability.health': {
|
||||
sorted = filtered.sort((a, b) => {
|
||||
const aHealth = a.health + a.turrets.at(-1)!.health;
|
||||
@@ -82,8 +91,10 @@ export const Results = memo(() => {
|
||||
case 'survivability.camouflageShooting':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.camouflageLoss -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.camouflageLoss,
|
||||
a.camouflage.still *
|
||||
a.turrets.at(-1)!.guns.at(-1)!.camouflageLoss -
|
||||
b.camouflage.still *
|
||||
b.turrets.at(-1)!.guns.at(-1)!.camouflageLoss,
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -187,16 +198,10 @@ export const Results = memo(() => {
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
resolveNearPenetration(
|
||||
(
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[1] ??
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0]
|
||||
).penetration,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[1]?.penetration ?? 0,
|
||||
) -
|
||||
resolveNearPenetration(
|
||||
(
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[1] ??
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0]
|
||||
).penetration,
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[1]?.penetration ?? 0,
|
||||
),
|
||||
);
|
||||
break;
|
||||
@@ -246,23 +251,26 @@ export const Results = memo(() => {
|
||||
(a, b) =>
|
||||
awaitedModelDefinitions[a.id].turrets[a.turrets.at(-1)!.id].guns[
|
||||
a.turrets.at(-1)!.guns.at(-1)!.id
|
||||
].pitch.max -
|
||||
].pitch.max +
|
||||
(awaitedModelDefinitions[a.id].turretRotation?.pitch ?? 0) -
|
||||
awaitedModelDefinitions[b.id].turrets[b.turrets.at(-1)!.id].guns[
|
||||
b.turrets.at(-1)!.guns.at(-1)!.id
|
||||
].pitch.max,
|
||||
].pitch.max -
|
||||
(awaitedModelDefinitions[b.id].turretRotation?.pitch ?? 0),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.gunElevation':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
// reversed because of negative values
|
||||
awaitedModelDefinitions[b.id].turrets[b.turrets.at(-1)!.id].guns[
|
||||
b.turrets.at(-1)!.guns.at(-1)!.id
|
||||
].pitch.min -
|
||||
].pitch.min +
|
||||
(awaitedModelDefinitions[b.id].turretRotation?.pitch ?? 0) -
|
||||
awaitedModelDefinitions[a.id].turrets[a.turrets.at(-1)!.id].guns[
|
||||
a.turrets.at(-1)!.guns.at(-1)!.id
|
||||
].pitch.min,
|
||||
].pitch.min -
|
||||
(awaitedModelDefinitions[a.id].turretRotation?.pitch ?? 0),
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -324,19 +332,26 @@ export const Results = memo(() => {
|
||||
break;
|
||||
}
|
||||
|
||||
return sort.direction === 'ascending' ? sorted : sorted.reverse();
|
||||
return filters.sort.direction === 'ascending' ? sorted : sorted.reverse();
|
||||
} else {
|
||||
const searchedRaw = go(filters.search, awaitedTankNames, {
|
||||
key: 'combined',
|
||||
limit: 25,
|
||||
});
|
||||
const searchedTanks = searchedRaw.map(
|
||||
(result) => awaitedTankDefinitions[result.obj.id],
|
||||
);
|
||||
return searchedTanks;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [search, sort]);
|
||||
}, [filters]);
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="4" flexGrow="1">
|
||||
<SearchBar topResult={searchedTanks?.[0]} />
|
||||
<SearchBar topResult={tanks?.[0]} />
|
||||
|
||||
{!search && !searching && <FilterControl />}
|
||||
{!filters.search && !filters.searching && <FilterControl />}
|
||||
|
||||
{testing === 'only' && (
|
||||
{filters.testing === 'only' && (
|
||||
<Flex justify="center" mt="4">
|
||||
<Callout.Root color="amber">
|
||||
<Callout.Icon>
|
||||
@@ -350,25 +365,21 @@ export const Results = memo(() => {
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
{!search && sort.by === 'meta.tier' && !searching && (
|
||||
<TierCard tier={tier} />
|
||||
)}
|
||||
|
||||
{(search || sort.by !== 'meta.tier') && !searching && searchedTanks && (
|
||||
{!filters.searching && (
|
||||
<>
|
||||
{searchedTanks.length > 0 && (
|
||||
{tanks.length > 0 && (
|
||||
<TankCardWrapper>
|
||||
{searchedTanks.map((tank) => (
|
||||
{tanks.map((tank) => (
|
||||
<TankCard key={tank.id} tank={tank} />
|
||||
))}
|
||||
</TankCardWrapper>
|
||||
)}
|
||||
|
||||
{searchedTanks.length === 0 && <NoResults type="search" />}
|
||||
{tanks.length === 0 && <NoResults type="search" />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{searching && (
|
||||
{filters.searching && (
|
||||
<TankCardWrapper>
|
||||
{times(Math.round(10 + 10 * Math.random()), (index) => (
|
||||
<SkeletonTankCard key={index} />
|
||||
|
||||
@@ -19,23 +19,18 @@ export function Sort() {
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Content align="end">
|
||||
<DropdownMenu.Label>Sort by</DropdownMenu.Label>
|
||||
<DropdownMenu.CheckboxItem
|
||||
checked={sort.by === 'meta.none'}
|
||||
onClick={() => {
|
||||
mutateTankopediaFilters((draft) => {
|
||||
draft.sort.by = 'meta.none';
|
||||
});
|
||||
}}
|
||||
>
|
||||
No sort
|
||||
</DropdownMenu.CheckboxItem>
|
||||
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger>Meta</DropdownMenu.SubTrigger>
|
||||
<DropdownMenu.SubContent>
|
||||
<DropdownMenu.CheckboxItem
|
||||
checked={sort.by === 'meta.tier'}
|
||||
onClick={() => {
|
||||
mutateTankopediaFilters((draft) => {
|
||||
draft.sort.by = 'meta.tier';
|
||||
});
|
||||
}}
|
||||
>
|
||||
Tier
|
||||
</DropdownMenu.CheckboxItem>
|
||||
</DropdownMenu.SubContent>
|
||||
</DropdownMenu.Sub>
|
||||
<DropdownMenu.Label>Sort by</DropdownMenu.Label>
|
||||
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger>Fire</DropdownMenu.SubTrigger>
|
||||
@@ -305,8 +300,6 @@ export function Sort() {
|
||||
</DropdownMenu.SubContent>
|
||||
</DropdownMenu.Sub>
|
||||
|
||||
<DropdownMenu.Separator />
|
||||
|
||||
<DropdownMenu.Label>Direction</DropdownMenu.Label>
|
||||
<DropdownMenu.RadioGroup
|
||||
value={sort.direction}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import { Flex, Text } from '@radix-ui/themes';
|
||||
import { Icon } from '@radix-ui/themes/dist/cjs/components/callout';
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import { use, useMemo } from 'react';
|
||||
import { classIcons } from '../../../../components/ClassIcon';
|
||||
import { Link } from '../../../../components/Link';
|
||||
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
|
||||
import { asset } from '../../../../core/blitzkit/asset';
|
||||
import { modelDefinitions } from '../../../../core/blitzkit/modelDefinitions';
|
||||
import { normalizeBoundingBox } from '../../../../core/blitzkit/normalizeBoundingBox';
|
||||
import { resolveDpm } from '../../../../core/blitzkit/resolveDpm';
|
||||
import { resolveReload } from '../../../../core/blitzkit/resolveReload';
|
||||
import { TankDefinition } from '../../../../core/blitzkit/tankDefinitions';
|
||||
import { tankIcon } from '../../../../core/blitzkit/tankIcon';
|
||||
import { unionBoundingBox } from '../../../../core/blitzkit/unionBoundingBox';
|
||||
import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
|
||||
import * as styles from './TankCard.css';
|
||||
|
||||
interface TankCardProps {
|
||||
@@ -12,47 +20,114 @@ interface TankCardProps {
|
||||
}
|
||||
|
||||
export function TankCard({ tank }: TankCardProps) {
|
||||
// const awaitedModelDefinitions = use(modelDefinitions);
|
||||
// const Icon = classIcons[tank.class];
|
||||
const awaitedModelDefinitions = use(modelDefinitions);
|
||||
const Icon = classIcons[tank.class];
|
||||
// const link = useRef<HTMLAnchorElement>(null);
|
||||
// const sortBy = useTankopediaFilters((state) => state.sort.by);
|
||||
// const discriminator = useMemo(() => {
|
||||
// if (sortBy.startsWith('meta')) return undefined;
|
||||
const sortBy = useTankopediaFilters((state) => state.sort.by);
|
||||
const discriminator = useMemo(() => {
|
||||
if (sortBy.startsWith('meta')) return undefined;
|
||||
|
||||
// const turret = tank.turrets.at(-1)!;
|
||||
// const gun = turret.guns.at(-1)!;
|
||||
// const shell = gun.shells[0];
|
||||
// const tracks = tank.tracks.at(-1)!;
|
||||
// const tankModelDefinition = awaitedModelDefinitions[tank.id];
|
||||
const turret = tank.turrets.at(-1)!;
|
||||
const gun = turret.guns.at(-1)!;
|
||||
const shell0 = gun.shells[0];
|
||||
const shell1 = gun.shells[1];
|
||||
const tracks = tank.tracks.at(-1)!;
|
||||
const engine = tank.engines.at(-1)!;
|
||||
const tankModelDefinition = awaitedModelDefinitions[tank.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
|
||||
// switch (sortBy) {
|
||||
// case 'fire.aimTime':
|
||||
// return `${gun.aimTime.toFixed(2)}s`;
|
||||
// case 'fire.caliber':
|
||||
// return `${shell.caliber.toFixed(0)}mm`;
|
||||
// case 'fire.damage':
|
||||
// return `${shell.damage.armor.toFixed(0)}hp`;
|
||||
// case 'fire.dispersionMoving':
|
||||
// return `+ ${tracks.dispersion.move.toFixed(3)}`;
|
||||
// case 'fire.dispersionStill':
|
||||
// return gun.dispersion.base.toFixed(3);
|
||||
// case 'fire.dpm':
|
||||
// return resolveDpm(gun, shell).toFixed(0);
|
||||
// case 'fire.gunDepression':
|
||||
// return awaitedModelDefinitions;
|
||||
// }
|
||||
// }, [sortBy]);
|
||||
switch (sortBy) {
|
||||
case 'fire.aimTime':
|
||||
return gun.aimTime.toFixed(2);
|
||||
case 'fire.caliber':
|
||||
return shell0.caliber.toFixed(0);
|
||||
case 'fire.damage':
|
||||
return shell0.damage.armor.toFixed(0);
|
||||
case 'fire.dispersionMoving':
|
||||
return tracks.dispersion.move.toFixed(3);
|
||||
case 'fire.dispersionStill':
|
||||
return gun.dispersion.base.toFixed(3);
|
||||
case 'fire.dpm':
|
||||
return resolveDpm(gun, shell0).toFixed(0);
|
||||
case 'fire.reload':
|
||||
return resolveReload(gun).toFixed(2);
|
||||
case 'fire.standardPenetration':
|
||||
return resolveNearPenetration(shell0.penetration).toFixed(0);
|
||||
case 'fire.premiumPenetration':
|
||||
return shell1
|
||||
? resolveNearPenetration(shell1.penetration).toFixed(0)
|
||||
: '--';
|
||||
case 'fire.shellVelocity':
|
||||
return shell0.speed.toFixed(0);
|
||||
case 'fire.gunDepression':
|
||||
return (
|
||||
gunModelDefinition.pitch.max +
|
||||
(tankModelDefinition.turretRotation?.pitch ?? 0)
|
||||
).toFixed(1);
|
||||
case 'fire.gunElevation':
|
||||
return (
|
||||
-gunModelDefinition.pitch.min -
|
||||
(tankModelDefinition.turretRotation?.pitch ?? 0)
|
||||
).toFixed(1);
|
||||
case 'maneuverability.forwardsSpeed':
|
||||
return tank.speed.forwards.toFixed(0);
|
||||
case 'maneuverability.backwardsSpeed':
|
||||
return tank.speed.backwards.toFixed(0);
|
||||
case 'maneuverability.power':
|
||||
return engine.power.toFixed(0);
|
||||
case 'maneuverability.powerToWeight':
|
||||
return (
|
||||
(1000 * engine.power) /
|
||||
(tank.weight +
|
||||
engine.weight +
|
||||
tracks.weight +
|
||||
turret.weight +
|
||||
gun.weight)
|
||||
).toFixed(1);
|
||||
case 'maneuverability.weight':
|
||||
return (
|
||||
(tank.weight +
|
||||
engine.weight +
|
||||
tracks.weight +
|
||||
turret.weight +
|
||||
gun.weight) /
|
||||
1000
|
||||
).toFixed(1);
|
||||
case 'maneuverability.traverseSpeed':
|
||||
return tracks.traverseSpeed.toFixed(1);
|
||||
case 'survivability.health':
|
||||
return (tank.health + turret.health).toFixed(0);
|
||||
case 'survivability.viewRange':
|
||||
return turret.viewRange.toFixed(0);
|
||||
case 'survivability.camouflageStill':
|
||||
return (tank.camouflage.still * 100).toFixed(0);
|
||||
case 'survivability.camouflageMoving':
|
||||
return (tank.camouflage.moving * 100).toFixed(0);
|
||||
case 'survivability.camouflageShooting':
|
||||
return (tank.camouflage.still * gun.camouflageLoss * 100).toFixed(0);
|
||||
case 'survivability.volume': {
|
||||
const dimensions = normalizeBoundingBox(
|
||||
unionBoundingBox(
|
||||
tankModelDefinition.boundingBox,
|
||||
turretModelDefinition.boundingBox,
|
||||
),
|
||||
);
|
||||
|
||||
// useEffect(() => {
|
||||
// const unsubscribe = useTankopediaFilters.subscribe((filters) => {
|
||||
// if (!link.current) return;
|
||||
return (dimensions[0] * dimensions[1] * dimensions[2]).toFixed(0);
|
||||
}
|
||||
|
||||
// const visible = tankopediaFilterTank(filters, tank);
|
||||
// link.current.style.display = visible ? 'flex' : 'none';
|
||||
// });
|
||||
|
||||
// return unsubscribe;
|
||||
// }, []);
|
||||
case 'survivability.length':
|
||||
return Math.max(
|
||||
...normalizeBoundingBox(
|
||||
unionBoundingBox(
|
||||
tankModelDefinition.boundingBox,
|
||||
turretModelDefinition.boundingBox,
|
||||
),
|
||||
),
|
||||
).toFixed(0);
|
||||
}
|
||||
}, [sortBy]);
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -89,7 +164,7 @@ export function TankCard({ tank }: TankCardProps) {
|
||||
</Text>
|
||||
</Flex>
|
||||
|
||||
{/* {discriminator && (
|
||||
{discriminator && (
|
||||
<Text
|
||||
mt="-2"
|
||||
color="gray"
|
||||
@@ -102,7 +177,7 @@ export function TankCard({ tank }: TankCardProps) {
|
||||
>
|
||||
{discriminator}
|
||||
</Text>
|
||||
)} */}
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ export function TankSearch({
|
||||
let sorted: TankDefinition[] = [];
|
||||
|
||||
switch (sort.by) {
|
||||
case 'meta.tier':
|
||||
case 'meta.none':
|
||||
sorted = filtered.sort((a, b) => a.tier - b.tier);
|
||||
break;
|
||||
|
||||
@@ -475,7 +475,7 @@ export function TankSearch({
|
||||
page: 0,
|
||||
},
|
||||
sort: {
|
||||
by: 'meta.tier',
|
||||
by: 'meta.none',
|
||||
direction: 'descending',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import { memo, use, useMemo } from 'react';
|
||||
import { TANK_CLASSES } from '../../../../components/Tanks/components/Item/constants';
|
||||
import { gameDefinitions } from '../../../../core/blitzkit/gameDefinitions';
|
||||
import {
|
||||
Tier,
|
||||
tanksDefinitionsArray,
|
||||
} from '../../../../core/blitzkit/tankDefinitions';
|
||||
import { tankopediaFilterTank } from '../../../../core/blitzkit/tankopediaFilterTank';
|
||||
import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
|
||||
import { NoResults } from './NoResults';
|
||||
import { TankCard } from './TankCard';
|
||||
import { TankCardWrapper } from './TankCardWrapper';
|
||||
import { treeTypeOrder } from './TankSearch/constants';
|
||||
|
||||
interface TierCardProps {
|
||||
tier: Tier;
|
||||
}
|
||||
|
||||
export const TierCard = memo(
|
||||
({ tier }: TierCardProps) => {
|
||||
const awaitedGameDefinitions = use(gameDefinitions);
|
||||
const awaitedTanksDefinitionsArray = use(tanksDefinitionsArray);
|
||||
const filters = useTankopediaFilters();
|
||||
const tanks = useMemo(
|
||||
() =>
|
||||
awaitedTanksDefinitionsArray
|
||||
.filter((tank) => tankopediaFilterTank(filters, tank))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
treeTypeOrder.indexOf(a.treeType) -
|
||||
treeTypeOrder.indexOf(b.treeType),
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class),
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
awaitedGameDefinitions.nations.indexOf(a.nation) -
|
||||
awaitedGameDefinitions.nations.indexOf(b.nation),
|
||||
),
|
||||
[tier, filters],
|
||||
);
|
||||
|
||||
if (tanks.length === 0) return <NoResults />;
|
||||
|
||||
return (
|
||||
<TankCardWrapper>
|
||||
{tanks.map((tank) => (
|
||||
<TankCard key={tank.id} tank={tank} />
|
||||
))}
|
||||
</TankCardWrapper>
|
||||
);
|
||||
},
|
||||
(prev, next) => prev.tier === next.tier,
|
||||
);
|
||||
@@ -13,7 +13,7 @@ export const TierFilter = memo(() => {
|
||||
const sort = useTankopediaFilters((state) => state.sort);
|
||||
const search = useTankopediaFilters((state) => state.search);
|
||||
|
||||
if (sort.by !== 'meta.tier' || search) return null;
|
||||
if (sort.by !== 'meta.none' || search) return null;
|
||||
|
||||
return (
|
||||
<Flex justify="center">
|
||||
|
||||
@@ -106,7 +106,7 @@ export type ArmorPiercingLayer =
|
||||
};
|
||||
|
||||
export const SORT_NAMES = {
|
||||
'meta.tier': 'tier',
|
||||
'meta.none': 'none',
|
||||
'survivability.health': 'health',
|
||||
'survivability.viewRange': 'view range',
|
||||
'survivability.camouflageStill': 'camouflage still',
|
||||
@@ -150,7 +150,7 @@ export const useTankopediaPersistent = create<TankopediaPersistent>()(
|
||||
},
|
||||
},
|
||||
sort: {
|
||||
by: 'meta.tier',
|
||||
by: 'meta.none',
|
||||
direction: 'descending',
|
||||
},
|
||||
filters: {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Tier } from '../core/blitzkit/tankDefinitions';
|
||||
import { TankopediaSortBy, TankopediaSortDirection } from './tankopedia';
|
||||
|
||||
export interface TankopediaFilters {
|
||||
tier: Tier;
|
||||
tier?: Tier;
|
||||
nation?: string;
|
||||
class?: TankClass;
|
||||
type?: TreeType;
|
||||
@@ -21,7 +21,7 @@ export interface TankopediaFilters {
|
||||
export const useTankopediaFilters = create<TankopediaFilters>()(() => ({
|
||||
testing: 'include',
|
||||
sort: {
|
||||
by: 'meta.tier',
|
||||
by: 'meta.none',
|
||||
direction: 'descending',
|
||||
},
|
||||
tier: 10,
|
||||
|
||||
Reference in new issue
Block a user