Skip to content

Commit

Permalink
chore!: create a more typed EsfFit (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
TrueBrain authored May 20, 2024
1 parent 955e884 commit e070121
Show file tree
Hide file tree
Showing 45 changed files with 1,377 additions and 768 deletions.
321 changes: 185 additions & 136 deletions .storybook/fits.ts

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions .storybook/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ export const withDecoratorFull = (Story: StoryFn) => (

export const useFitSelection = (fit: EsfFit | null) => {
const currentFit = useCurrentFit();
const setFit = currentFit.setFit;

const setFitRef = React.useRef(currentFit.setFit);
setFitRef.current = currentFit.setFit;

React.useEffect(() => {
setFit(fit);
}, [setFit, fit]);
setFitRef.current(fit);
}, [fit]);
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
},
"peerDependencies": {
"@eveshipfit/data": "^9",
"@eveshipfit/dogma-engine": "^4",
"@eveshipfit/dogma-engine": "^5",
"react": "^18",
"react-dom": "^18"
},
Expand Down
9 changes: 5 additions & 4 deletions src/components/CalculationDetail/CalculationDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import React from "react";

import { Icon } from "@/components/Icon";
import { useEveData } from "@/providers/EveDataProvider";
import { StatisticsItemAttribute, StatisticsItemAttributeEffect, useStatistics } from "@/providers/StatisticsProvider";
import { useStatistics } from "@/providers/StatisticsProvider";
import { CalculationItemAttribute, CalculationItemAttributeEffect } from "@/providers/DogmaEngineProvider";

import styles from "./CalculationDetail.module.css";

Expand Down Expand Up @@ -42,7 +43,7 @@ function stateToInteger(state: string): number {
}
}

const Effect = (props: { effect: StatisticsItemAttributeEffect }) => {
const Effect = (props: { effect: CalculationItemAttributeEffect }) => {
const eveData = useEveData();
const statistics = useStatistics();

Expand Down Expand Up @@ -123,7 +124,7 @@ const Effect = (props: { effect: StatisticsItemAttributeEffect }) => {
);
};

const CalculationDetailMeta = (props: { attributeId: number; attribute: StatisticsItemAttribute }) => {
const CalculationDetailMeta = (props: { attributeId: number; attribute: CalculationItemAttribute }) => {
const [expanded, setExpanded] = React.useState(false);
const eveData = useEveData();

Expand Down Expand Up @@ -175,7 +176,7 @@ export const CalculationDetail = (props: {
const statistics = useStatistics();
if (statistics === null) return <></>;

let attributes: [number, StatisticsItemAttribute][] = [];
let attributes: [number, CalculationItemAttribute][] = [];

if (props.source === "Ship") {
attributes = [...(statistics.hull.attributes.entries() ?? [])];
Expand Down
19 changes: 14 additions & 5 deletions src/components/DroneBay/DroneBay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ import React from "react";
import { CharAttribute, ShipAttribute } from "@/components/ShipAttribute";
import { useFitManager } from "@/providers/FitManagerProvider";
import { useEveData } from "@/providers/EveDataProvider";
import { StatisticsItem, useStatistics } from "@/providers/StatisticsProvider";
import { useStatistics } from "@/providers/StatisticsProvider";
import { CalculationItem } from "@/providers/DogmaEngineProvider";

import styles from "./DroneBay.module.css";

const DroneBayEntrySelected = ({ drone, index, isOpen }: { drone: StatisticsItem; index: number; isOpen: boolean }) => {
const DroneBayEntrySelected = ({
drone,
index,
isOpen,
}: {
drone: CalculationItem;
index: number;
isOpen: boolean;
}) => {
const fitManager = useFitManager();

const onClick = React.useCallback(() => {
Expand All @@ -29,7 +38,7 @@ const DroneBayEntrySelected = ({ drone, index, isOpen }: { drone: StatisticsItem
);
};

const DroneBayEntry = ({ name, drones }: { name: string; drones: StatisticsItem[] }) => {
const DroneBayEntry = ({ name, drones }: { name: string; drones: CalculationItem[] }) => {
const eveData = useEveData();
const statistics = useStatistics();
const fitManager = useFitManager();
Expand Down Expand Up @@ -93,8 +102,8 @@ export const DroneBay = () => {
if (eveData === null || statistics === null) return <></>;

/* Group drones by type_id */
const dronesGrouped: Record<string, StatisticsItem[]> = {};
for (const drone of statistics.items.filter((item) => item.flag == 87)) {
const dronesGrouped: Record<string, CalculationItem[]> = {};
for (const drone of statistics.items.filter((item) => item.slot.type == "DroneBay")) {
const name = eveData.typeIDs?.[drone.type_id].name ?? "";

if (dronesGrouped[name] === undefined) {
Expand Down
6 changes: 4 additions & 2 deletions src/components/FitButtonBar/ClipboardButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ModalDialog } from "@/components/ModalDialog";
import { useClipboard } from "@/hooks/Clipboard";
import { useExportEft } from "@/hooks/ExportEft";
import { useImportEft } from "@/hooks/ImportEft";
import { useImportEsiFitting } from "@/hooks/ImportEsiFitting";
import { EsfFit } from "@/providers/CurrentFitProvider";
import { useFitManager } from "@/providers/FitManagerProvider";

Expand All @@ -14,6 +15,7 @@ export const ClipboardButton = () => {
const fitManager = useFitManager();
const exportEft = useExportEft();
const importEft = useImportEft();
const importEsiFitting = useImportEsiFitting();
const { copy, copied } = useClipboard();

const [isPopupOpen, setIsPopupOpen] = React.useState(false);
Expand Down Expand Up @@ -42,7 +44,7 @@ export const ClipboardButton = () => {

let fit: EsfFit | undefined | null;
if (fitString.startsWith("{")) {
fit = JSON.parse(fitString);
fit = importEsiFitting(JSON.parse(fitString));
} else {
try {
fit = importEft(fitString);
Expand All @@ -66,7 +68,7 @@ export const ClipboardButton = () => {

setIsPasteOpen(false);
setIsPopupOpen(false);
}, [fitManager, importEft]);
}, [fitManager, importEft, importEsiFitting]);

return (
<>
Expand Down
37 changes: 19 additions & 18 deletions src/components/HardwareListing/HardwareListing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import React from "react";
import { defaultDataUrl } from "@/settings";
import { Icon } from "@/components/Icon";
import { TreeListing, TreeHeader, TreeLeaf } from "@/components/TreeListing";
import { StatisticsSlotType, useStatistics } from "@/providers/StatisticsProvider";
import { useStatistics } from "@/providers/StatisticsProvider";
import { useFitManager } from "@/providers/FitManagerProvider";
import { useEveData } from "@/providers/EveDataProvider";
import { CalculationSlotType } from "@/providers/DogmaEngineProvider";

import styles from "./HardwareListing.module.css";

Expand All @@ -21,7 +22,7 @@ interface ListingItem {
name: string;
meta: number;
typeId: number;
slotType: StatisticsSlotType | "droneBay" | "charge";
slotType: CalculationSlotType;
}

interface ListingGroup {
Expand All @@ -43,14 +44,14 @@ interface Filter {

const OnItemDragStart = (
typeId: number,
slotType: StatisticsSlotType | "droneBay" | "charge",
slotType: CalculationSlotType,
): ((e: React.DragEvent<HTMLDivElement>) => void) => {
return (e: React.DragEvent<HTMLDivElement>) => {
const img = new Image();
img.src = `https://images.evetech.net/types/${typeId}/icon?size=64`;
e.dataTransfer.setDragImage(img, 32, 32);
e.dataTransfer.setData("application/type_id", typeId.toString());
e.dataTransfer.setData("application/slot_type", slotType);
e.dataTransfer.setData("application/esf-type-id", typeId.toString());
e.dataTransfer.setData("application/esf-slot-type", slotType);
};
};

Expand Down Expand Up @@ -193,35 +194,35 @@ export const HardwareListing = () => {
if (module.marketGroupID === undefined) continue;
if (!module.published) continue;

let slotType: StatisticsSlotType | "droneBay" | "charge" | undefined;
let slotType: CalculationSlotType | undefined;
if (module.categoryID !== 8) {
slotType = eveData.typeDogma[typeId]?.dogmaEffects
.map((effect) => {
switch (effect.effectID) {
case eveData.effectMapping.loPower:
return "lowslot";
return "Low";
case eveData.effectMapping.medPower:
return "medslot";
return "Medium";
case eveData.effectMapping.hiPower:
return "hislot";
return "High";
case eveData.effectMapping.rigSlot:
return "rig";
return "Rig";
case eveData.effectMapping.subSystem:
return "subsystem";
return "SubSystem";
}
})
.filter((slot) => slot !== undefined)[0];
if (module.categoryID === 18) {
slotType = "droneBay";
slotType = "DroneBay";
}

if (slotType === undefined) continue;

if (filter.lowslot || filter.medslot || filter.hislot || filter.rig_subsystem || filter.drone) {
if (slotType === "lowslot" && !filter.lowslot) continue;
if (slotType === "medslot" && !filter.medslot) continue;
if (slotType === "hislot" && !filter.hislot) continue;
if ((slotType === "rig" || slotType === "subsystem") && !filter.rig_subsystem) continue;
if (slotType === "Low" && !filter.lowslot) continue;
if (slotType === "Medium" && !filter.medslot) continue;
if (slotType === "High" && !filter.hislot) continue;
if ((slotType === "Rig" || slotType === "SubSystem") && !filter.rig_subsystem) continue;
if (module.categoryID === 18 && !filter.drone) continue;
}
} else {
Expand All @@ -236,13 +237,13 @@ export const HardwareListing = () => {
for (const chargeGroupID of filter.moduleWithCharge.chargeGroupIDs) {
if (module.groupID !== chargeGroupID) continue;

slotType = "charge";
slotType = "Charge";
break;
}

if (slotType === undefined) continue;
} else {
slotType = "charge";
slotType = "Charge";
}
}

Expand Down
22 changes: 11 additions & 11 deletions src/components/HullListing/HullListing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const Hull = (props: { typeId: number; entry: ListingHull }) => {

return (
<TreeLeaf
key={`${fit.fit.ship_type_id}-${index}`}
key={`${fit.fit.shipTypeId}-${index}`}
level={4}
content={fit.fit.name}
onClick={() => fitManager.setFit(fit.fit)}
Expand Down Expand Up @@ -166,13 +166,13 @@ export const HullListing = () => {
const localFitsGrouped = React.useMemo(() => {
const grouped: Record<string, ListingFit[]> = {};
for (const fit of localFits.fittings) {
if (fit.ship_type_id === undefined) continue;
if (fit.shipTypeId === undefined) continue;

if (grouped[fit.ship_type_id] === undefined) {
grouped[fit.ship_type_id] = [];
if (grouped[fit.shipTypeId] === undefined) {
grouped[fit.shipTypeId] = [];
}

grouped[fit.ship_type_id].push({
grouped[fit.shipTypeId].push({
origin: "local",
fit,
});
Expand All @@ -186,13 +186,13 @@ export const HullListing = () => {

const grouped: Record<string, ListingFit[]> = {};
for (const fit of characterFittings) {
if (fit.ship_type_id === undefined) continue;
if (fit.shipTypeId === undefined) continue;

if (grouped[fit.ship_type_id] === undefined) {
grouped[fit.ship_type_id] = [];
if (grouped[fit.shipTypeId] === undefined) {
grouped[fit.shipTypeId] = [];
}

grouped[fit.ship_type_id].push({
grouped[fit.shipTypeId].push({
origin: "character",
fit,
});
Expand All @@ -213,15 +213,15 @@ export const HullListing = () => {
if (hull.marketGroupID === undefined) continue;
if (!hull.published) continue;

if (filter.currentHull && currentFit.fit?.ship_type_id !== parseInt(typeId)) continue;
if (filter.currentHull && currentFit.fit?.shipTypeId !== parseInt(typeId)) continue;

const fits: ListingFit[] = [];
if (anyFilter) {
if (filter.localFits && Object.keys(localFitsGrouped).includes(typeId)) fits.push(...localFitsGrouped[typeId]);
if (filter.characterFits && Object.keys(characterFitsGrouped).includes(typeId))
fits.push(...characterFitsGrouped[typeId]);
if (fits.length == 0) {
if (!filter.currentHull || currentFit.fit?.ship_type_id !== parseInt(typeId)) continue;
if (!filter.currentHull || currentFit.fit?.shipTypeId !== parseInt(typeId)) continue;
}
} else {
if (Object.keys(localFitsGrouped).includes(typeId)) fits.push(...localFitsGrouped[typeId]);
Expand Down
2 changes: 1 addition & 1 deletion src/components/ShipFit/Hull.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const Hull = () => {
return <></>;
}

const shipTypeId = currentFit.fit.ship_type_id;
const shipTypeId = currentFit.fit.shipTypeId;
if (shipTypeId === undefined) {
return <></>;
}
Expand Down
12 changes: 6 additions & 6 deletions src/components/ShipFit/HullDraggable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";

import { useFitManager } from "@/providers/FitManagerProvider";
import { StatisticsSlotType } from "@/providers/StatisticsProvider";
import { CalculationSlotType } from "@/providers/DogmaEngineProvider";

import styles from "./ShipFit.module.css";

Expand All @@ -21,11 +21,11 @@ export const HullDraggable = () => {
return Number.isInteger(num) ? num : undefined;
};

const draggedTypeId: number | undefined = parseNumber(e.dataTransfer.getData("application/type_id"));
const draggedSlotId: number | undefined = parseNumber(e.dataTransfer.getData("application/slot_id"));
const draggedSlotType: StatisticsSlotType | "droneBay" | "charge" = e.dataTransfer.getData(
"application/slot_type",
) as StatisticsSlotType | "droneBay" | "charge";
const draggedTypeId: number | undefined = parseNumber(e.dataTransfer.getData("application/esf-type-id"));
const draggedSlotId: number | undefined = parseNumber(e.dataTransfer.getData("application/esf-slot-index"));
const draggedSlotType: CalculationSlotType = e.dataTransfer.getData(
"application/esf-slot-type",
) as CalculationSlotType;

if (draggedTypeId === undefined) {
return;
Expand Down
8 changes: 4 additions & 4 deletions src/components/ShipFit/RadialMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ import React from "react";
import styles from "./ShipFit.module.css";

const highlightSettings = {
lowslot: {
Low: {
width: 12,
height: 3,
x: 0,
y: 9,
},
medslot: {
Medium: {
width: 3,
height: 12,
x: 9,
y: 0,
},
hislot: {
High: {
width: 12,
height: 3,
x: 0,
y: 0,
},
};

export const RadialMenu = (props: { type: "lowslot" | "medslot" | "hislot" }) => {
export const RadialMenu = (props: { type: "Low" | "Medium" | "High" }) => {
const highlight = highlightSettings[props.type];

return (
Expand Down
Loading

0 comments on commit e070121

Please sign in to comment.