``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
245 lines
7.7 KiB
TypeScript
245 lines
7.7 KiB
TypeScript
import React, { useContext } from "react";
|
|
|
|
import {
|
|
Collapsible,
|
|
CollapsibleHeaderContent,
|
|
CollapsibleHeading,
|
|
} from "@dndbeyond/character-components/es";
|
|
import {
|
|
CampaignUtils,
|
|
CharacterTheme,
|
|
Container,
|
|
ContainerUtils,
|
|
InventoryManager,
|
|
CharacterCurrencyContract,
|
|
Item,
|
|
ItemUtils,
|
|
PartyInfo,
|
|
RuleData,
|
|
CoinManager,
|
|
} from "@dndbeyond/character-rules-engine/es";
|
|
|
|
import { ItemName } from "~/components/ItemName";
|
|
import { NumberDisplay } from "~/components/NumberDisplay";
|
|
|
|
import CurrencyCollapsible from "../../../CharacterSheet/components/CurrencyCollapsible";
|
|
import { CurrencyErrorTypeEnum } from "../../containers/panes/CurrencyPane/CurrencyPaneConstants";
|
|
import { CoinManagerContext } from "../../managers/CoinManagerContext";
|
|
import { InventoryManagerContext } from "../../managers/InventoryManagerContext";
|
|
import { CustomItemCreator } from "../CustomItemCreator";
|
|
import EquipmentShop from "../EquipmentShop";
|
|
import ItemDetail from "../ItemDetail";
|
|
import { ItemSlotManager } from "../ItemSlotManager";
|
|
import { ThemeButtonWithMenu } from "../common/Button";
|
|
|
|
interface Props {
|
|
currentContainer: Container;
|
|
theme: CharacterTheme;
|
|
onItemMove?: (item: Item, containerDefinitionKey: string) => void;
|
|
onItemEquip?: (item: Item, uses: number) => void;
|
|
ruleData: RuleData;
|
|
proficiencyBonus: number;
|
|
inventory: Array<Item>;
|
|
containers: Array<Container>;
|
|
shopOpenInitially?: boolean;
|
|
isReadonly: boolean;
|
|
partyInfo: PartyInfo | null;
|
|
inventoryManager: InventoryManager;
|
|
coinManager: CoinManager;
|
|
handleCurrencyChangeError: (
|
|
currencyName: string,
|
|
errorType: CurrencyErrorTypeEnum
|
|
) => void;
|
|
handleCurrencyAdjust: (
|
|
coin: Partial<CharacterCurrencyContract>,
|
|
multiplier: 1 | -1,
|
|
containerDefinitionKey: string
|
|
) => void;
|
|
handleAmountSet: (
|
|
containerDefinitionKey: string,
|
|
key: keyof CharacterCurrencyContract,
|
|
amount: number
|
|
) => void;
|
|
}
|
|
|
|
export const ContainerActionsComponent: React.FC<Props> = ({
|
|
currentContainer,
|
|
theme,
|
|
ruleData,
|
|
onItemMove,
|
|
onItemEquip,
|
|
proficiencyBonus,
|
|
inventory,
|
|
containers,
|
|
shopOpenInitially = false,
|
|
isReadonly,
|
|
partyInfo,
|
|
inventoryManager,
|
|
coinManager,
|
|
handleCurrencyAdjust,
|
|
handleAmountSet,
|
|
handleCurrencyChangeError,
|
|
}) => {
|
|
let showEquipmentShop = true;
|
|
if (
|
|
ContainerUtils.isShared(currentContainer) &&
|
|
partyInfo &&
|
|
CampaignUtils.isSharingStateInactive(
|
|
CampaignUtils.getSharingState(partyInfo)
|
|
)
|
|
) {
|
|
showEquipmentShop = false;
|
|
}
|
|
|
|
let headerNode: React.ReactNode = (
|
|
<CollapsibleHeaderContent
|
|
heading={
|
|
<CollapsibleHeading>{`Contents (${inventory.length})`}</CollapsibleHeading>
|
|
}
|
|
callout={
|
|
<div className="ct-equipment-manage-pane__callout">
|
|
<NumberDisplay
|
|
type="weightInLb"
|
|
number={ContainerUtils.getWeightInfo(currentContainer).total}
|
|
/>
|
|
</div>
|
|
}
|
|
/>
|
|
);
|
|
|
|
return (
|
|
<div className="ct-container-manager">
|
|
{showEquipmentShop && (
|
|
<Collapsible
|
|
header="Add Items"
|
|
initiallyCollapsed={!shopOpenInitially}
|
|
overrideCollapsed={!shopOpenInitially}
|
|
>
|
|
<EquipmentShop
|
|
limitAddToCurrentContainer={currentContainer}
|
|
partyInfo={partyInfo}
|
|
containers={containers}
|
|
theme={theme}
|
|
ruleData={ruleData}
|
|
proficiencyBonus={proficiencyBonus}
|
|
/>
|
|
<CustomItemCreator containers={[currentContainer]} />
|
|
</Collapsible>
|
|
)}
|
|
{coinManager.canUseCointainers() && (
|
|
<CurrencyCollapsible
|
|
heading={`${ContainerUtils.getName(currentContainer)} Coin`}
|
|
initiallyCollapsed={true}
|
|
isReadonly={isReadonly}
|
|
container={currentContainer}
|
|
handleCurrencyChangeError={handleCurrencyChangeError}
|
|
handleCurrencyAdjust={handleCurrencyAdjust}
|
|
handleAmountSet={handleAmountSet}
|
|
/>
|
|
)}
|
|
<Collapsible
|
|
header={headerNode}
|
|
initiallyCollapsed={shopOpenInitially}
|
|
overrideCollapsed={shopOpenInitially}
|
|
>
|
|
<div className="ct-container-manager__inventory">
|
|
{inventory.map((item, idx) => {
|
|
const canEquip = inventoryManager.canEquipUnequipItem(item);
|
|
const key = ItemUtils.getUniqueKey(item);
|
|
|
|
return (
|
|
<Collapsible
|
|
key={`${key}-${idx}`}
|
|
className="ct-container-manager__item"
|
|
layoutType={"minimal"}
|
|
header={
|
|
<CollapsibleHeaderContent
|
|
heading={
|
|
<div className="ct-container-manager__item-header">
|
|
<div className="ct-container-manager__item-header-action">
|
|
<ItemSlotManager
|
|
isUsed={!!ItemUtils.isEquipped(item)}
|
|
isReadonly={isReadonly}
|
|
canUse={canEquip}
|
|
onSet={(uses) => {
|
|
if (onItemEquip) {
|
|
onItemEquip(item, uses);
|
|
}
|
|
}}
|
|
theme={theme}
|
|
useTooltip={false}
|
|
/>
|
|
</div>
|
|
<div className="ct-container-manager__item-header-name">
|
|
<ItemName item={item} showLegacy={true} />
|
|
</div>
|
|
</div>
|
|
}
|
|
callout={
|
|
!isReadonly &&
|
|
partyInfo &&
|
|
inventoryManager.canMoveItem(item) ? (
|
|
<ThemeButtonWithMenu
|
|
showSingleOption={true}
|
|
containerEl={
|
|
document.querySelector(
|
|
".ct-sidebar__portal"
|
|
) as HTMLElement
|
|
}
|
|
groupedOptions={ContainerUtils.getGroupedOptions(
|
|
ItemUtils.getContainerDefinitionKey(item),
|
|
containers,
|
|
"Move To:",
|
|
CampaignUtils.getSharingState(partyInfo)
|
|
)}
|
|
buttonStyle="outline"
|
|
onSelect={(definitionKey) => {
|
|
if (onItemMove) {
|
|
onItemMove(item, definitionKey);
|
|
}
|
|
}}
|
|
>
|
|
Move
|
|
</ThemeButtonWithMenu>
|
|
) : null
|
|
}
|
|
/>
|
|
}
|
|
>
|
|
<ItemDetail
|
|
theme={theme}
|
|
item={item}
|
|
ruleData={ruleData}
|
|
showCustomize={false}
|
|
showImage={false}
|
|
proficiencyBonus={proficiencyBonus}
|
|
/>
|
|
</Collapsible>
|
|
);
|
|
})}
|
|
{ContainerUtils.getItemMappingIds(currentContainer).length === 0 && (
|
|
<div className="ct-container-manager__empty">
|
|
There are no items in your{" "}
|
|
{ContainerUtils.getName(currentContainer)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Collapsible>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const ContainerActions = (props) => {
|
|
const { inventoryManager } = useContext(InventoryManagerContext);
|
|
const { coinManager } = useContext(CoinManagerContext);
|
|
return (
|
|
<ContainerActionsComponent
|
|
inventoryManager={inventoryManager}
|
|
coinManager={coinManager}
|
|
{...props}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default ContainerActions;
|