diff --git a/src/HullListing/HullListing.tsx b/src/HullListing/HullListing.tsx index eabae1a..e47b438 100644 --- a/src/HullListing/HullListing.tsx +++ b/src/HullListing/HullListing.tsx @@ -4,19 +4,24 @@ import React from "react"; import { EsiContext } from "../EsiProvider"; import { EsiFit, ShipSnapshotContext } from "../ShipSnapshotProvider"; import { EveDataContext } from "../EveDataProvider"; -import { Icon } from "../Icon"; +import { Icon, IconName } from "../Icon"; import { TreeListing, TreeHeader, TreeHeaderAction, TreeLeaf } from "../TreeListing"; import { LocalFitContext } from "../LocalFitProvider"; import styles from "./HullListing.module.css"; interface ListingFit { + origin: "local" | "esi-character"; + fit: EsiFit; +} + +interface ListingHull { name: string; - fits: EsiFit[]; + fits: ListingFit[]; } interface ListingHulls { - [typeId: string]: ListingFit; + [typeId: string]: ListingHull; } interface ListingGroup { @@ -35,7 +40,7 @@ const factionIdToRace: Record = { 1: "Non-Empire", } as const; -const Hull = (props: { typeId: number, entry: ListingFit }) => { +const Hull = (props: { typeId: number, entry: ListingHull }) => { const shipSnapShot = React.useContext(ShipSnapshotContext); const getChildren = React.useCallback(() => { @@ -43,9 +48,24 @@ const Hull = (props: { typeId: number, entry: ListingFit }) => { return ; } else { let index = 0; - return <>{props.entry.fits.sort((a, b) => a.name.localeCompare(b.name)).map((fit) => { + return <>{props.entry.fits.sort((a, b) => a.fit.name.localeCompare(b.fit.name)).map((fit) => { index += 1; - return shipSnapShot.changeFit(fit)} />; + + let icon: IconName | undefined; + let iconTitle: string | undefined; + switch (fit.origin) { + case "local": + icon = "fitting-local"; + iconTitle = "Browser-stored fitting"; + break; + + case "esi-character": + icon = "fitting-character"; + iconTitle = "In-game personal fitting"; + break; + } + + return shipSnapShot.changeFit(fit.fit)} icon={icon} iconTitle={iconTitle} />; })}; } }, [props, shipSnapShot]); @@ -106,14 +126,14 @@ export const HullListing = () => { currentHull: false, }); - const [localCharacterFits, setLocalCharacterFits] = React.useState>({}); - const [esiCharacterFits, setEsiCharacterFits] = React.useState>({}); + const [localCharacterFits, setLocalCharacterFits] = React.useState>({}); + const [esiCharacterFits, setEsiCharacterFits] = React.useState>({}); React.useEffect(() => { if (!localFit.loaded) return; if (!localFit.fittings) return; - const newLocalCharacterFits: Record = {}; + const newLocalCharacterFits: Record = {}; for (const fit of localFit.fittings) { if (fit.ship_type_id === undefined) continue; @@ -121,7 +141,10 @@ export const HullListing = () => { newLocalCharacterFits[fit.ship_type_id] = []; } - newLocalCharacterFits[fit.ship_type_id].push(fit); + newLocalCharacterFits[fit.ship_type_id].push({ + origin: "local", + fit + }); } setLocalCharacterFits(newLocalCharacterFits); @@ -133,7 +156,7 @@ export const HullListing = () => { const charFittings = esi.characters[esi.currentCharacter].charFittings || []; - const newEsiCharacterFits: Record = {}; + const newEsiCharacterFits: Record = {}; for (const fit of charFittings) { if (fit.ship_type_id === undefined) continue; @@ -141,7 +164,10 @@ export const HullListing = () => { newEsiCharacterFits[fit.ship_type_id] = []; } - newEsiCharacterFits[fit.ship_type_id].push(fit); + newEsiCharacterFits[fit.ship_type_id].push({ + origin: "esi-character", + fit, + }); } setEsiCharacterFits(newEsiCharacterFits); @@ -161,7 +187,7 @@ export const HullListing = () => { if (filter.currentHull && shipSnapShot.fit?.ship_type_id !== parseInt(typeId)) continue; - const fits: EsiFit[] = []; + const fits: ListingFit[] = []; if (anyFilter) { if (filter.localCharacter && Object.keys(localCharacterFits).includes(typeId)) fits.push(...localCharacterFits[typeId]); if (filter.esiCharacter && Object.keys(esiCharacterFits).includes(typeId)) fits.push(...esiCharacterFits[typeId]); diff --git a/src/TreeListing/TreeListing.module.css b/src/TreeListing/TreeListing.module.css index 1ab579c..237f672 100644 --- a/src/TreeListing/TreeListing.module.css +++ b/src/TreeListing/TreeListing.module.css @@ -36,4 +36,12 @@ .leaf { cursor: pointer; + position: relative; +} + +.leafIcon { + left: -16px; + margin-top: 2px; + pointer-events: none; + position: absolute; } diff --git a/src/TreeListing/TreeListing.tsx b/src/TreeListing/TreeListing.tsx index 7557419..af7305c 100644 --- a/src/TreeListing/TreeListing.tsx +++ b/src/TreeListing/TreeListing.tsx @@ -41,7 +41,7 @@ export const TreeHeader = (props: { icon?: string, text: string, action?: React. } -export const TreeLeaf = (props: { level: number, height?: number, content: string, onClick?: (e: React.MouseEvent) => void }) => { +export const TreeLeaf = (props: { level: number, height?: number, icon?: IconName, iconTitle?: string, content: string, onClick?: (e: React.MouseEvent) => void }) => { const stylesHeader = styles[`header${props.level}`]; const height = props.height ?? 20; @@ -50,6 +50,9 @@ export const TreeLeaf = (props: { level: number, height?: number, content: strin return
+ {props.icon !== undefined && + + } {props.content}