New source found from dndbeyond.com
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
import { FC, HTMLAttributes, useContext, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import {
|
||||
Action,
|
||||
ActionUtils,
|
||||
Constants,
|
||||
DataOrigin,
|
||||
EntityUtils,
|
||||
HelperUtils,
|
||||
Infusion,
|
||||
InfusionUtils,
|
||||
ItemPlanUtils,
|
||||
ItemUtils,
|
||||
Spell,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { EditableName } from "~/components/EditableName";
|
||||
import { ItemName } from "~/components/ItemName";
|
||||
import { useSidebar } from "~/contexts/Sidebar";
|
||||
import { useCharacterEngine } from "~/hooks/useCharacterEngine";
|
||||
import { Header } from "~/subApps/sheet/components/Sidebar/components/Header";
|
||||
import { Preview } from "~/subApps/sheet/components/Sidebar/components/Preview";
|
||||
import {
|
||||
getDataOriginComponentInfo,
|
||||
getSpellComponentInfo,
|
||||
} from "~/subApps/sheet/components/Sidebar/helpers/paneUtils";
|
||||
import {
|
||||
PaneComponentEnum,
|
||||
PaneIdentifiersItem,
|
||||
} from "~/subApps/sheet/components/Sidebar/types";
|
||||
import ItemDetail from "~/tools/js/Shared/components/ItemDetail";
|
||||
import ItemListInformationCollapsible from "~/tools/js/Shared/components/ItemListInformationCollapsible";
|
||||
import { InventoryManagerContext } from "~/tools/js/Shared/managers/InventoryManagerContext";
|
||||
import { appEnvSelectors } from "~/tools/js/Shared/selectors";
|
||||
import { PaneIdentifierUtils } from "~/tools/js/Shared/utils";
|
||||
|
||||
import { PaneInitFailureContent } from "../../components/PaneInitFailureContent";
|
||||
|
||||
interface Props extends HTMLAttributes<HTMLDivElement> {
|
||||
identifiers: PaneIdentifiersItem | null;
|
||||
}
|
||||
export const ItemPane: FC<Props> = ({ identifiers, ...props }) => {
|
||||
const { inventoryManager } = useContext(InventoryManagerContext);
|
||||
const {
|
||||
pane: { paneHistoryPush },
|
||||
} = useSidebar();
|
||||
const {
|
||||
ruleData,
|
||||
allInventoryItems: items,
|
||||
weaponSpellDamageGroups,
|
||||
entityValueLookup,
|
||||
snippetData,
|
||||
infusionChoiceLookup,
|
||||
characterTheme: theme,
|
||||
containerLookup,
|
||||
partyInfo,
|
||||
itemPlans,
|
||||
} = useCharacterEngine();
|
||||
const isReadonly = useSelector(appEnvSelectors.getIsReadonly);
|
||||
|
||||
const [isCustomizeClosed, setIsCustomizeClosed] = useState(true);
|
||||
const [shouldShowPaneInitFailure, setShouldShowPaneInitFailure] =
|
||||
useState(true);
|
||||
|
||||
const item =
|
||||
items.find((item) => identifiers?.id === ItemUtils.getMappingId(item)) ??
|
||||
null;
|
||||
|
||||
const handleToggleCustomize = () => {
|
||||
setIsCustomizeClosed(!isCustomizeClosed);
|
||||
};
|
||||
|
||||
const handleCustomItemEdit = (adjustments: Record<string, any>): void => {
|
||||
if (item === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (adjustments.notes === "") {
|
||||
adjustments.notes = null;
|
||||
}
|
||||
|
||||
inventoryManager.handleCustomEdit({
|
||||
item,
|
||||
adjustments,
|
||||
});
|
||||
};
|
||||
|
||||
const handleCustomDataUpdate = (
|
||||
adjustmentType: Constants.AdjustmentTypeEnum,
|
||||
value: any
|
||||
): void => {
|
||||
if (item) {
|
||||
inventoryManager.handleCustomizationSet({
|
||||
item,
|
||||
adjustmentType,
|
||||
value,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveCustomizations = (): void => {
|
||||
if (item) {
|
||||
inventoryManager.handleCustomizationsRemove({ item });
|
||||
}
|
||||
};
|
||||
|
||||
const handleDataOriginClick = (dataOrigin: DataOrigin) => {
|
||||
let component = getDataOriginComponentInfo(dataOrigin);
|
||||
if (component.type !== PaneComponentEnum.ERROR_404) {
|
||||
paneHistoryPush(component.type, component.identifiers);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSpellClick = (spell: Spell): void => {
|
||||
let component = getSpellComponentInfo(spell);
|
||||
if (component.type) {
|
||||
paneHistoryPush(component.type, component.identifiers);
|
||||
}
|
||||
};
|
||||
|
||||
const handleInfusionClick = (infusion: Infusion): void => {
|
||||
const choiceKey = InfusionUtils.getChoiceKey(infusion);
|
||||
if (choiceKey !== null) {
|
||||
paneHistoryPush(
|
||||
PaneComponentEnum.INFUSION_CHOICE,
|
||||
PaneIdentifierUtils.generateInfusionChoice(choiceKey)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleActionClick = (action: Action): void => {
|
||||
const dataOrigin = ActionUtils.getDataOrigin(action);
|
||||
let component = getDataOriginComponentInfo(dataOrigin);
|
||||
if (component.type !== PaneComponentEnum.ERROR_404) {
|
||||
paneHistoryPush(component.type, component.identifiers);
|
||||
}
|
||||
};
|
||||
|
||||
const handleParentClick = (): void => {
|
||||
if (item) {
|
||||
const itemPlan = ItemUtils.getItemPlan(item, itemPlans);
|
||||
if (itemPlan) {
|
||||
const dataOrigin = ItemPlanUtils.getDataOrigin(itemPlan);
|
||||
let component = getDataOriginComponentInfo(dataOrigin);
|
||||
if (component.type !== PaneComponentEnum.ERROR_404) {
|
||||
paneHistoryPush(component.type, component.identifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (item === null) {
|
||||
return shouldShowPaneInitFailure ? (
|
||||
<PaneInitFailureContent
|
||||
errorTitle="Item Not Found"
|
||||
errorMessage="That item is no longer in your inventory! Please try again."
|
||||
toastMeta={{ level: "info" }}
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
|
||||
let parentName: string | null = null;
|
||||
const itemPlan = ItemUtils.getItemPlan(item, itemPlans);
|
||||
if (itemPlan) {
|
||||
const dataOrigin = ItemPlanUtils.getDataOrigin(itemPlan);
|
||||
parentName = EntityUtils.getDataOriginName(dataOrigin);
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
<Header
|
||||
parent={parentName}
|
||||
onClick={handleParentClick}
|
||||
preview={<Preview imageUrl={ItemUtils.getAvatarUrl(item)} />}
|
||||
>
|
||||
<EditableName onClick={handleToggleCustomize}>
|
||||
<ItemName item={item} />
|
||||
</EditableName>
|
||||
</Header>
|
||||
<ItemListInformationCollapsible item={item} ruleData={ruleData} />
|
||||
<ItemDetail
|
||||
theme={theme}
|
||||
key={ItemUtils.getUniqueKey(item)}
|
||||
item={item}
|
||||
weaponSpellDamageGroups={weaponSpellDamageGroups}
|
||||
ruleData={ruleData}
|
||||
snippetData={snippetData}
|
||||
onCustomDataUpdate={handleCustomDataUpdate}
|
||||
onCustomizationsRemove={handleRemoveCustomizations}
|
||||
onDataOriginClick={handleDataOriginClick}
|
||||
onSpellClick={handleSpellClick}
|
||||
onInfusionClick={handleInfusionClick}
|
||||
onMasteryActionClick={handleActionClick}
|
||||
entityValueLookup={entityValueLookup}
|
||||
infusionChoiceLookup={infusionChoiceLookup}
|
||||
isReadonly={isReadonly}
|
||||
container={HelperUtils.lookupDataOrFallback(
|
||||
containerLookup,
|
||||
ItemUtils.getContainerDefinitionKey(item)
|
||||
)}
|
||||
showCustomize={!isReadonly}
|
||||
onPostRemoveNavigation={PaneComponentEnum.EQUIPMENT_MANAGE}
|
||||
partyInfo={partyInfo}
|
||||
onCustomItemEdit={handleCustomItemEdit}
|
||||
isCustomizeClosed={isCustomizeClosed}
|
||||
onCustomizeClick={handleToggleCustomize}
|
||||
onRemoveItem={() => setShouldShowPaneInitFailure(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user