feat: upgrade ComparePersistent

This commit is contained in:
TrèsAbhi committed 2025-09-01 23:02:20 -05:00
1 parent c2d625e1ed
commit ef2a47e756
3 files changed
+54 -72

No files matched your search

@@ -1,14 +1,14 @@
import { PlusIcon, TrashIcon } from '@radix-ui/react-icons'; import { PlusIcon, TrashIcon } from "@radix-ui/react-icons";
import { Button, Dialog, Flex, SegmentedControl } from '@radix-ui/themes'; import { Button, Dialog, Flex, SegmentedControl } from "@radix-ui/themes";
import { awaitableProvisionDefinitions } from '../../core/awaitables/provisionDefinitions'; import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDefinitions";
import { tankToCompareMember } from '../../core/blitzkit/tankToCompareMember'; import { tankToCompareMember } from "../../core/blitzkit/tankToCompareMember";
import { useLocale } from '../../hooks/useLocale'; import { useLocale } from "../../hooks/useLocale";
import { CompareEphemeral } from '../../stores/compareEphemeral'; import { CompareEphemeral } from "../../stores/compareEphemeral";
import { import {
ComparePersistent, ComparePersistent,
type DeltaMode, type DeltaMode,
} from '../../stores/comparePersistent'; } from "../../stores/comparePersistent";
import { TankSearch } from '../TankSearch'; import { TankSearch } from "../TankSearch";
interface ControlsProps { interface ControlsProps {
addTankDialogOpen: boolean; addTankDialogOpen: boolean;
@@ -23,7 +23,6 @@ export function Controls({
}: ControlsProps) { }: ControlsProps) {
const deltaMode = ComparePersistent.use((state) => state.deltaMode); const deltaMode = ComparePersistent.use((state) => state.deltaMode);
const mutateCompareEphemeral = CompareEphemeral.useMutation(); const mutateCompareEphemeral = CompareEphemeral.useMutation();
const mutateComparePersistent = ComparePersistent.useMutation();
const { strings } = useLocale(); const { strings } = useLocale();
return ( return (
@@ -58,7 +57,7 @@ export function Controls({
onSelect={(tank) => { onSelect={(tank) => {
mutateCompareEphemeral((draft) => { mutateCompareEphemeral((draft) => {
draft.members.push( draft.members.push(
tankToCompareMember(tank, provisionDefinitions), tankToCompareMember(tank, provisionDefinitions)
); );
draft.sorting = undefined; draft.sorting = undefined;
}); });
@@ -69,7 +68,7 @@ export function Controls({
draft.members.push( draft.members.push(
...tanks.map((tank) => { ...tanks.map((tank) => {
return tankToCompareMember(tank, provisionDefinitions); return tankToCompareMember(tank, provisionDefinitions);
}), })
); );
draft.sorting = undefined; draft.sorting = undefined;
}); });
@@ -98,18 +97,18 @@ export function Controls({
variant="classic" variant="classic"
value={deltaMode} value={deltaMode}
onValueChange={(value) => { onValueChange={(value) => {
mutateComparePersistent((draft) => { ComparePersistent.mutate((draft) => {
draft.deltaMode = value as DeltaMode; draft.deltaMode = value as DeltaMode;
}); });
}} }}
> >
<SegmentedControl.Item value={'none' satisfies DeltaMode}> <SegmentedControl.Item value={"none" satisfies DeltaMode}>
{strings.website.tools.compare.actions.deltas.none} {strings.website.tools.compare.actions.deltas.none}
</SegmentedControl.Item> </SegmentedControl.Item>
<SegmentedControl.Item value={'percentage' satisfies DeltaMode}> <SegmentedControl.Item value={"percentage" satisfies DeltaMode}>
{strings.website.tools.compare.actions.deltas.percentage} {strings.website.tools.compare.actions.deltas.percentage}
</SegmentedControl.Item> </SegmentedControl.Item>
<SegmentedControl.Item value={'absolute' satisfies DeltaMode}> <SegmentedControl.Item value={"absolute" satisfies DeltaMode}>
{strings.website.tools.compare.actions.deltas.absolute} {strings.website.tools.compare.actions.deltas.absolute}
</SegmentedControl.Item> </SegmentedControl.Item>
</SegmentedControl.Root> </SegmentedControl.Root>
@@ -1,26 +1,25 @@
import { createDefaultSkills } from '@blitzkit/core'; import { createDefaultSkills } from "@blitzkit/core";
import { Flex, Heading, Text } from '@radix-ui/themes'; import { Flex, Heading, Text } from "@radix-ui/themes";
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from "react";
import { CompareTable } from '../../../components/Compare/CompareTable'; import { CompareTable } from "../../../components/Compare/CompareTable";
import { Controls } from '../../../components/Compare/Controls'; import { Controls } from "../../../components/Compare/Controls";
import { DamageWarning } from '../../../components/DamageWarning'; import { DamageWarning } from "../../../components/DamageWarning";
import { PageWrapper } from '../../../components/PageWrapper'; import { PageWrapper } from "../../../components/PageWrapper";
import { awaitableEquipmentDefinitions } from '../../../core/awaitables/equipmentDefinitions'; import { awaitableEquipmentDefinitions } from "../../../core/awaitables/equipmentDefinitions";
import { awaitableModelDefinitions } from '../../../core/awaitables/modelDefinitions'; import { awaitableModelDefinitions } from "../../../core/awaitables/modelDefinitions";
import { awaitableProvisionDefinitions } from '../../../core/awaitables/provisionDefinitions'; import { awaitableProvisionDefinitions } from "../../../core/awaitables/provisionDefinitions";
import { awaitableSkillDefinitions } from '../../../core/awaitables/skillDefinitions'; import { awaitableSkillDefinitions } from "../../../core/awaitables/skillDefinitions";
import { awaitableTankDefinitions } from '../../../core/awaitables/tankDefinitions'; import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions";
import { tankCharacteristics } from '../../../core/blitzkit/tankCharacteristics'; import { tankCharacteristics } from "../../../core/blitzkit/tankCharacteristics";
import { tankToCompareMember } from '../../../core/blitzkit/tankToCompareMember'; import { tankToCompareMember } from "../../../core/blitzkit/tankToCompareMember";
import { import {
type LocaleAcceptorProps, type LocaleAcceptorProps,
LocaleProvider, LocaleProvider,
useLocale, useLocale,
} from '../../../hooks/useLocale'; } from "../../../hooks/useLocale";
import { App } from '../../../stores/app'; import { App } from "../../../stores/app";
import { CompareEphemeral } from '../../../stores/compareEphemeral'; import { CompareEphemeral } from "../../../stores/compareEphemeral";
import { ComparePersistent } from '../../../stores/comparePersistent'; import { TankopediaPersistent } from "../../../stores/tankopediaPersistent";
import { TankopediaPersistent } from '../../../stores/tankopediaPersistent';
const [ const [
modelDefinitions, modelDefinitions,
@@ -41,13 +40,11 @@ export function Page({ locale }: LocaleAcceptorProps) {
<LocaleProvider locale={locale}> <LocaleProvider locale={locale}>
<App.Provider> <App.Provider>
<TankopediaPersistent.Provider> <TankopediaPersistent.Provider>
<ComparePersistent.Provider> <CompareEphemeral.Provider
<CompareEphemeral.Provider data={createDefaultSkills(skillDefinitions)}
data={createDefaultSkills(skillDefinitions)} >
> <Content />
<Content /> </CompareEphemeral.Provider>
</CompareEphemeral.Provider>
</ComparePersistent.Provider>
</TankopediaPersistent.Provider> </TankopediaPersistent.Provider>
</App.Provider> </App.Provider>
</LocaleProvider> </LocaleProvider>
@@ -72,18 +69,15 @@ function Content() {
stockTurret: thisMember.tank.turrets[0], stockTurret: thisMember.tank.turrets[0],
applyReactiveArmor: members.some( applyReactiveArmor: members.some(
(member) => (member) =>
member.key !== thisMember.key && member.key !== thisMember.key && member.consumables.includes(33)
member.consumables.includes(33),
), ),
applyDynamicArmor: members.some( applyDynamicArmor: members.some(
(member) => (member) =>
member.key !== thisMember.key && member.key !== thisMember.key && member.consumables.includes(73)
member.consumables.includes(73),
), ),
applySpallLiner: members.some( applySpallLiner: members.some(
(member) => (member) =>
member.key !== thisMember.key && member.key !== thisMember.key && member.provisions.includes(101)
member.provisions.includes(101),
), ),
assaultDistance: thisMember.assaultDistance, assaultDistance: thisMember.assaultDistance,
}, },
@@ -91,20 +85,20 @@ function Content() {
equipmentDefinitions: equipmentDefinitions, equipmentDefinitions: equipmentDefinitions,
provisionDefinitions: provisionDefinitions, provisionDefinitions: provisionDefinitions,
tankModelDefinition: modelDefinitions.models[thisMember.tank.id], tankModelDefinition: modelDefinitions.models[thisMember.tank.id],
}, }
), )
), ),
[members, crewSkills], [members, crewSkills]
); );
const mutateCompareEphemeral = CompareEphemeral.useMutation(); const mutateCompareEphemeral = CompareEphemeral.useMutation();
useEffect(() => { useEffect(() => {
const search = new URLSearchParams(window.location.search); const search = new URLSearchParams(window.location.search);
const tanksQuery = search.get('tanks'); const tanksQuery = search.get("tanks");
if (tanksQuery === null) return; if (tanksQuery === null) return;
const tanks = tanksQuery.split(',').map(Number); const tanks = tanksQuery.split(",").map(Number);
mutateCompareEphemeral((draft) => { mutateCompareEphemeral((draft) => {
draft.members = []; draft.members = [];
@@ -122,12 +116,12 @@ function Content() {
useEffect(() => { useEffect(() => {
const search = new URLSearchParams(window.location.search); const search = new URLSearchParams(window.location.search);
search.set('tanks', members.map((member) => member.tank.id).join(',')); search.set("tanks", members.map((member) => member.tank.id).join(","));
window.history.replaceState( window.history.replaceState(
{}, {},
'', "",
`${window.location.pathname}?${search.toString()}`, `${window.location.pathname}?${search.toString()}`
); );
}, [members]); }, [members]);
@@ -1,23 +1,12 @@
import * as lodash from 'lodash-es'; import { Varuna } from "varuna";
import { create } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware'; export type DeltaMode = "none" | "percentage" | "absolute";
import { createContextualStore } from '../core/zustand/createContextualStore';
export type DeltaMode = 'none' | 'percentage' | 'absolute';
export interface ComparePersistent { export interface ComparePersistent {
deltaMode: DeltaMode; deltaMode: DeltaMode;
} }
export const ComparePersistent = createContextualStore(() => export const ComparePersistent = new Varuna<ComparePersistent>(
create<ComparePersistent>()( { deltaMode: "none" },
persist( "compare-2"
subscribeWithSelector<ComparePersistent>(() => ({
deltaMode: 'none',
})),
{
name: 'compare',
merge: (a, b) => lodash.merge(b, a),
},
),
),
); );