import { groupBy, orderBy } from "lodash"; import React, { useContext } from "react"; import { connect } from "react-redux"; import { AttunementSlot } from "@dndbeyond/character-components/es"; import { rulesEngineSelectors, Item, ItemUtils, CampaignUtils, CharacterTheme, InventoryManager, serviceDataSelectors, PartyInfo, } from "@dndbeyond/character-rules-engine/es"; import { useSidebar } from "~/contexts/Sidebar"; import { PaneInfo } from "~/contexts/Sidebar/Sidebar"; import { PaneComponentEnum } from "~/subApps/sheet/components/Sidebar/types"; import { InventoryManagerContext } from "../../../Shared/managers/InventoryManagerContext"; import { PaneIdentifierUtils } from "../../../Shared/utils"; import { SheetAppState } from "../../typings"; import AttunementItem from "./AttunementItem"; interface Props { items: Array; attunedSlots: Array; isFiltered: boolean; isMobile: boolean; theme: CharacterTheme; inventoryManager: InventoryManager; partyInfo: PartyInfo | null; paneHistoryStart: PaneInfo["paneHistoryStart"]; } class Attunement extends React.PureComponent { static defaultProps = { isFiltered: false, isMobile: false, }; handleItemShow = (item: Item): void => { const { paneHistoryStart } = this.props; paneHistoryStart( PaneComponentEnum.ITEM_DETAIL, PaneIdentifierUtils.generateItem(ItemUtils.getMappingId(item)) ); }; renderItems = (): React.ReactNode => { const { items, theme, inventoryManager, partyInfo } = this.props; const attunableItems = items.filter((item) => ItemUtils.canAttune(item)); const sortedItems = groupBy( orderBy( attunableItems, [ (item) => ItemUtils.getRarityLevel(item), (item) => ItemUtils.getName(item), (item) => ItemUtils.getMappingId(item), ], ["desc", "asc"] ), (item) => { if (inventoryManager.isShared(item)) { return "party"; } else { return "character"; } } ); return (
Items Requiring Attunement
{sortedItems.character?.length > 0 ? ( sortedItems.character?.map((item) => ( )) ) : (
Items that you can attune to will display here as you make them active.
)}
{partyInfo && CampaignUtils.isSharingStateActive( CampaignUtils.getSharingState(partyInfo) ) && ( <>
Party Items Requiring Attunement
{sortedItems.party?.length > 0 ? ( sortedItems.party?.map((item) => ( )) ) : (
Party items that you can attune to will display here as you make them active.
)}
)}
); }; renderAttuned = (): React.ReactNode => { const { attunedSlots, isMobile, theme } = this.props; return (
Attuned Items
{attunedSlots.map((slot, idx) => ( ))}
); }; render() { return (
{this.renderAttuned()} {this.renderItems()}
); } } function mapStateToProps(state: SheetAppState) { return { attunedSlots: rulesEngineSelectors.getAttunedSlots(state), theme: rulesEngineSelectors.getCharacterTheme(state), items: rulesEngineSelectors.getEquippedItems(state), partyInfo: serviceDataSelectors.getPartyInfo(state), }; } const AttunementContainer = (props) => { const { inventoryManager } = useContext(InventoryManagerContext); const { pane: { paneHistoryStart }, } = useSidebar(); return ( ); }; export default connect(mapStateToProps)(AttunementContainer);