mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: migrate compare store
This commit is contained in:
1 parent
f423f8f797
commit
8b70aa12e4
8 files changed
+115
-92
No files matched your search
@@ -4,7 +4,7 @@ import Link from 'next/link';
|
||||
import { use, useState } from 'react';
|
||||
import { provisionDefinitions } from '../../../../core/blitzkit/provisionDefinitions';
|
||||
import { tankToCompareMember } from '../../../../core/blitzkit/tankToCompareMember';
|
||||
import { mutateCompareTemporary } from '../../../../stores/compare';
|
||||
import * as CompareEphemeral from '../../../../stores/compareEphemeral';
|
||||
import { TankSearch } from '../../tankopedia/components/TankSearch';
|
||||
|
||||
interface TankControlProps {
|
||||
@@ -15,13 +15,14 @@ interface TankControlProps {
|
||||
export function TankControl({ index, id }: TankControlProps) {
|
||||
const awaitedProvisionDefinitions = use(provisionDefinitions);
|
||||
const [switchTankDialogOpen, setSwitchTankDialogOpen] = useState(false);
|
||||
const mutateCompareEphemeral = CompareEphemeral.useMutation();
|
||||
|
||||
return (
|
||||
<Flex gap="3" justify="center" style={{ width: '100%' }}>
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members.splice(index, 1);
|
||||
draft.sorting = undefined;
|
||||
});
|
||||
@@ -51,7 +52,7 @@ export function TankControl({ index, id }: TankControlProps) {
|
||||
<TankSearch
|
||||
compact
|
||||
onSelect={(tank) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index] = tankToCompareMember(
|
||||
tank,
|
||||
awaitedProvisionDefinitions,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { ReactNode } from 'react';
|
||||
import * as CompareEphemeral from '../../../stores/compareEphemeral';
|
||||
import * as ComparePersistent from '../../../stores/comparePersistent';
|
||||
import * as TankFilters from '../../../stores/tankFilters';
|
||||
import * as TankopediaSort from '../../../stores/tankopediaSort';
|
||||
|
||||
export default function Layout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<TankopediaSort.Provider>
|
||||
<TankFilters.Provider>
|
||||
<ComparePersistent.Provider>
|
||||
<CompareEphemeral.Provider>{children}</CompareEphemeral.Provider>
|
||||
</ComparePersistent.Provider>
|
||||
</TankFilters.Provider>
|
||||
</TankopediaSort.Provider>
|
||||
);
|
||||
}
|
||||
@@ -50,13 +50,8 @@ import { tankIcon } from '../../../core/blitzkit/tankIcon';
|
||||
import { tankToCompareMember } from '../../../core/blitzkit/tankToCompareMember';
|
||||
import { BlitzkitButtonWatermark } from '../../../icons/BlitzkitButtonWatermark';
|
||||
import { theme } from '../../../stitches.config';
|
||||
import {
|
||||
DeltaMode,
|
||||
mutateComparePersistent,
|
||||
mutateCompareTemporary,
|
||||
useComparePersistent,
|
||||
useCompareTemporary,
|
||||
} from '../../../stores/compare';
|
||||
import * as CompareEphemeral from '../../../stores/compareEphemeral';
|
||||
import * as ComparePersistent from '../../../stores/comparePersistent';
|
||||
import { EquipmentMatrix } from '../../../stores/duel';
|
||||
import { permanentSkills } from '../tankopedia/[id]/components/Characteristics/components/Skills/constants';
|
||||
import { TankSearch } from '../tankopedia/components/TankSearch';
|
||||
@@ -71,14 +66,16 @@ export default function Page() {
|
||||
const awaitedSkillDefinitions = use(skillDefinitions);
|
||||
const awaitedConsumableDefinitions = use(consumableDefinitions);
|
||||
const searchParams = useSearchParams();
|
||||
const members = useCompareTemporary((state) => state.members);
|
||||
const members = CompareEphemeral.use((state) => state.members);
|
||||
const [addTankDialogOpen, setAddTankDialogOpen] = useState(false);
|
||||
const sorting = useCompareTemporary((state) => state.sorting);
|
||||
const sorting = CompareEphemeral.use((state) => state.sorting);
|
||||
const awaitedModelDefinitions = use(modelDefinitions);
|
||||
const awaitedEquipmentDefinitions = use(equipmentDefinitions);
|
||||
const awaitedProvisionDefinitions = use(provisionDefinitions);
|
||||
const deltaMode = useComparePersistent((state) => state.deltaMode);
|
||||
const crewSkills = useCompareTemporary((state) => state.crewSkills);
|
||||
const deltaMode = ComparePersistent.use((state) => state.deltaMode);
|
||||
const crewSkills = CompareEphemeral.use((state) => state.crewSkills);
|
||||
const mutateCompareEphemeral = CompareEphemeral.useMutation();
|
||||
const mutateComparePersistent = ComparePersistent.useMutation();
|
||||
const haveReactive = members.some((member) =>
|
||||
member.consumables.includes(33),
|
||||
);
|
||||
@@ -151,7 +148,7 @@ export default function Page() {
|
||||
const tanksParam = searchParams.get('tanks');
|
||||
|
||||
if (tanksParam) {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members = tanksParam
|
||||
.split(',')
|
||||
.map(Number)
|
||||
@@ -165,7 +162,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
if (Object.keys(crewSkills).length === 0) {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.crewSkills = createDefaultSkills(awaitedSkillDefinitions);
|
||||
});
|
||||
}
|
||||
@@ -210,7 +207,7 @@ export default function Page() {
|
||||
color={sorting?.by === name ? undefined : 'gray'}
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members.sort((memberA, memberB) => {
|
||||
const indexA = draft.members.indexOf(memberA);
|
||||
const indexB = draft.members.indexOf(memberB);
|
||||
@@ -413,7 +410,7 @@ export default function Page() {
|
||||
|
||||
if (dropIndex === -1) return;
|
||||
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
const fromIndex = index;
|
||||
const toIndex = dropIndex > index ? dropIndex - 1 : dropIndex;
|
||||
|
||||
@@ -558,7 +555,7 @@ export default function Page() {
|
||||
<TankSearch
|
||||
compact
|
||||
onSelect={(tank) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members.push(
|
||||
tankToCompareMember(
|
||||
tank,
|
||||
@@ -570,7 +567,7 @@ export default function Page() {
|
||||
setAddTankDialogOpen(false);
|
||||
}}
|
||||
onSelectAll={(tanks) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members.push(
|
||||
...tanks.map((tank) =>
|
||||
tankToCompareMember(
|
||||
@@ -593,7 +590,7 @@ export default function Page() {
|
||||
variant="soft"
|
||||
color="red"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members = [];
|
||||
draft.sorting = undefined;
|
||||
});
|
||||
@@ -606,17 +603,23 @@ export default function Page() {
|
||||
value={deltaMode}
|
||||
onValueChange={(value) => {
|
||||
mutateComparePersistent((draft) => {
|
||||
draft.deltaMode = value as DeltaMode;
|
||||
draft.deltaMode = value as ComparePersistent.DeltaMode;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SegmentedControl.Item value={'none' satisfies DeltaMode}>
|
||||
<SegmentedControl.Item
|
||||
value={'none' satisfies ComparePersistent.DeltaMode}
|
||||
>
|
||||
No deltas
|
||||
</SegmentedControl.Item>
|
||||
<SegmentedControl.Item value={'percentage' satisfies DeltaMode}>
|
||||
<SegmentedControl.Item
|
||||
value={'percentage' satisfies ComparePersistent.DeltaMode}
|
||||
>
|
||||
Percentage
|
||||
</SegmentedControl.Item>
|
||||
<SegmentedControl.Item value={'absolute' satisfies DeltaMode}>
|
||||
<SegmentedControl.Item
|
||||
value={'absolute' satisfies ComparePersistent.DeltaMode}
|
||||
>
|
||||
Absolute
|
||||
</SegmentedControl.Item>
|
||||
</SegmentedControl.Root>
|
||||
@@ -716,7 +719,7 @@ export default function Page() {
|
||||
<CrewSkillManager
|
||||
skillLevels={crewSkills}
|
||||
onChange={(skills) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.crewSkills = skills;
|
||||
});
|
||||
}}
|
||||
@@ -726,7 +729,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
Object.keys(draft.crewSkills).forEach(
|
||||
(skill) => {
|
||||
draft.crewSkills[skill] = 0;
|
||||
@@ -740,7 +743,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
Object.keys(draft.crewSkills).forEach(
|
||||
(skill) => {
|
||||
draft.crewSkills[skill] = 7;
|
||||
@@ -836,7 +839,7 @@ export default function Page() {
|
||||
engine={engine}
|
||||
track={track}
|
||||
onChange={(modules) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index] = {
|
||||
...draft.members[index],
|
||||
...modules,
|
||||
@@ -849,7 +852,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
const member = draft.members[index];
|
||||
|
||||
member.turret = member.tank.turrets[0];
|
||||
@@ -865,7 +868,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
const member = draft.members[index];
|
||||
|
||||
member.turret =
|
||||
@@ -952,7 +955,7 @@ export default function Page() {
|
||||
tank.provisions === provisions.length
|
||||
}
|
||||
onChange={(provisions) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].provisions =
|
||||
provisions;
|
||||
});
|
||||
@@ -963,7 +966,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].provisions = [];
|
||||
});
|
||||
}}
|
||||
@@ -1036,7 +1039,7 @@ export default function Page() {
|
||||
matrix={equipmentMatrix}
|
||||
preset={equipmentPreset}
|
||||
onChange={(matrix) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].equipmentMatrix =
|
||||
matrix;
|
||||
draft.sorting = undefined;
|
||||
@@ -1049,7 +1052,7 @@ export default function Page() {
|
||||
variant="ghost"
|
||||
color="red"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].equipmentMatrix =
|
||||
times(3, () =>
|
||||
times(3, () => 0),
|
||||
@@ -1063,7 +1066,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members.forEach((member) => {
|
||||
member.equipmentMatrix =
|
||||
draft.members[
|
||||
@@ -1141,7 +1144,7 @@ export default function Page() {
|
||||
consumables={consumablesList}
|
||||
selected={consumables}
|
||||
onChange={(consumables) => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].consumables =
|
||||
consumables;
|
||||
});
|
||||
@@ -1155,7 +1158,7 @@ export default function Page() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].consumables = [];
|
||||
});
|
||||
}}
|
||||
@@ -1209,7 +1212,7 @@ export default function Page() {
|
||||
marginLeft: shellIndex === 0 ? 0 : -1,
|
||||
}}
|
||||
onClick={() => {
|
||||
mutateCompareTemporary((draft) => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].shell = thisShell;
|
||||
});
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { uniqueId } from 'lodash';
|
||||
import { CompareMember } from '../../stores/compare';
|
||||
import { CompareMember } from '../../stores/compareEphemeral';
|
||||
import { ProvisionDefinitions } from './provisionDefinitions';
|
||||
import { TankDefinition } from './tankDefinitions';
|
||||
import { tankToDuelMember } from './tankToDuelMember';
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { produce } from 'immer';
|
||||
import { merge } from 'lodash';
|
||||
import { create } from 'zustand';
|
||||
import { persist, subscribeWithSelector } from 'zustand/middleware';
|
||||
import { DuelMember } from './duel';
|
||||
|
||||
export interface CompareMember extends DuelMember {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface CompareTemporary {
|
||||
crewSkills: Record<string, number>;
|
||||
members: CompareMember[];
|
||||
sorting?: {
|
||||
direction: 'ascending' | 'descending';
|
||||
by: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type DeltaMode = 'none' | 'percentage' | 'absolute';
|
||||
export interface ComparePersistent {
|
||||
deltaMode: DeltaMode;
|
||||
}
|
||||
|
||||
export const useCompareTemporary = create<CompareTemporary>()(() => ({
|
||||
crewSkills: {},
|
||||
members: [],
|
||||
}));
|
||||
|
||||
export const useComparePersistent = create<ComparePersistent>()(
|
||||
persist(
|
||||
subscribeWithSelector<ComparePersistent>(() => ({
|
||||
deltaMode: 'none',
|
||||
})),
|
||||
{
|
||||
name: 'compare',
|
||||
merge: (a, b) => merge(b, a),
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
export function mutateCompareTemporary(
|
||||
recipe: (draft: CompareTemporary) => void,
|
||||
) {
|
||||
useCompareTemporary.setState(produce(recipe));
|
||||
}
|
||||
|
||||
export function mutateComparePersistent(
|
||||
recipe: (draft: ComparePersistent) => void,
|
||||
) {
|
||||
useComparePersistent.setState(produce(recipe));
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
'use client';
|
||||
|
||||
import { create } from 'zustand';
|
||||
import { createNextSafeStore } from '../core/zustand/createNextSafeStore';
|
||||
import { DuelMember } from './duel';
|
||||
|
||||
export interface CompareMember extends DuelMember {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface CompareEphemeral {
|
||||
crewSkills: Record<string, number>;
|
||||
members: CompareMember[];
|
||||
sorting?: {
|
||||
direction: 'ascending' | 'descending';
|
||||
by: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const { Provider, use, useMutation, useStore } = createNextSafeStore(
|
||||
() =>
|
||||
create<CompareEphemeral>()(() => ({
|
||||
crewSkills: {},
|
||||
members: [],
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
'use client';
|
||||
|
||||
import { merge } from 'lodash';
|
||||
import { create } from 'zustand';
|
||||
import { persist, subscribeWithSelector } from 'zustand/middleware';
|
||||
import { createNextSafeStore } from '../core/zustand/createNextSafeStore';
|
||||
|
||||
export type DeltaMode = 'none' | 'percentage' | 'absolute';
|
||||
export interface ComparePersistent {
|
||||
deltaMode: DeltaMode;
|
||||
}
|
||||
|
||||
export const { Provider, use, useMutation, useStore } = createNextSafeStore(
|
||||
() =>
|
||||
create<ComparePersistent>()(
|
||||
persist(
|
||||
subscribeWithSelector<ComparePersistent>(() => ({
|
||||
deltaMode: 'none',
|
||||
})),
|
||||
{
|
||||
name: 'compare',
|
||||
merge: (a, b) => merge(b, a),
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -1,3 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { merge } from 'lodash';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
|
||||
Reference in new issue
Block a user