Grabbed dndbeyond's source code
``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
This commit is contained in:
+127
@@ -0,0 +1,127 @@
|
||||
import { orderBy } from "lodash";
|
||||
import React from "react";
|
||||
import { connect, DispatchProp } from "react-redux";
|
||||
|
||||
import {
|
||||
rulesEngineSelectors,
|
||||
characterActions,
|
||||
ConditionUtils,
|
||||
Condition,
|
||||
Constants,
|
||||
ConditionContract,
|
||||
RuleData,
|
||||
RuleDataUtils,
|
||||
CharacterTheme,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { Header } from "~/subApps/sheet/components/Sidebar/components/Header";
|
||||
|
||||
import * as appEnvSelectors from "../../../selectors/appEnv";
|
||||
import { SharedAppState } from "../../../stores/typings";
|
||||
import ConditionManagePaneSpecialConditions from "./ConditionManagePaneSpecialConditions";
|
||||
import ConditionManagePaneStandardConditions from "./ConditionManagePaneStandardConditions";
|
||||
|
||||
interface Props extends DispatchProp {
|
||||
activeConditions: Array<Condition>;
|
||||
ruleData: RuleData;
|
||||
isReadonly: boolean;
|
||||
theme: CharacterTheme;
|
||||
}
|
||||
class ConditionManagePane extends React.PureComponent<Props> {
|
||||
handleStandardConditionToggle = (
|
||||
condition: ConditionContract,
|
||||
isEnabled: boolean
|
||||
): void => {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
if (isEnabled) {
|
||||
dispatch(characterActions.conditionAdd(ConditionUtils.getId(condition)));
|
||||
} else {
|
||||
dispatch(
|
||||
characterActions.conditionRemove(ConditionUtils.getId(condition))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
handleSpecialConditionLevelChange = (
|
||||
condition: ConditionContract,
|
||||
conditionLevel: number | null
|
||||
): void => {
|
||||
const { dispatch, activeConditions } = this.props;
|
||||
|
||||
const conditionId = ConditionUtils.getId(condition);
|
||||
if (conditionLevel === null) {
|
||||
dispatch(characterActions.conditionRemove(conditionId));
|
||||
} else {
|
||||
const foundActiveCondition = activeConditions.find(
|
||||
(activeCondition) =>
|
||||
ConditionUtils.getId(activeCondition) === conditionId
|
||||
);
|
||||
|
||||
if (foundActiveCondition) {
|
||||
dispatch(characterActions.conditionSet(conditionId, conditionLevel));
|
||||
} else {
|
||||
dispatch(characterActions.conditionAdd(conditionId, conditionLevel));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { activeConditions, ruleData, isReadonly, theme } = this.props;
|
||||
|
||||
const conditionData = RuleDataUtils.getConditions(ruleData);
|
||||
|
||||
const displayedConditions = orderBy(conditionData, (condition) =>
|
||||
ConditionUtils.getName(condition)
|
||||
);
|
||||
const activeConditionIds = activeConditions.map((condition) =>
|
||||
ConditionUtils.getId(condition)
|
||||
);
|
||||
|
||||
const standardConditions = displayedConditions.filter(
|
||||
(condition) =>
|
||||
ConditionUtils.getType(condition) ===
|
||||
Constants.ConditionTypeEnum.STANDARD
|
||||
);
|
||||
const specialConditions = displayedConditions.filter(
|
||||
(condition) =>
|
||||
ConditionUtils.getType(condition) ===
|
||||
Constants.ConditionTypeEnum.SPECIAL
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="ct-condition-manage-pane">
|
||||
<Header>Conditions</Header>
|
||||
<div className="ct-condition-manage-pane__conditions">
|
||||
<ConditionManagePaneStandardConditions
|
||||
standardConditions={standardConditions}
|
||||
activeConditionIds={activeConditionIds}
|
||||
onConditionToggle={this.handleStandardConditionToggle}
|
||||
isReadonly={isReadonly}
|
||||
theme={theme}
|
||||
/>
|
||||
</div>
|
||||
<div className="ct-condition-manage-pane__conditions ct-condition-manage-pane__condition--special">
|
||||
<ConditionManagePaneSpecialConditions
|
||||
specialConditions={specialConditions}
|
||||
activeConditions={activeConditions}
|
||||
isReadonly={isReadonly}
|
||||
onConditionLevelChange={this.handleSpecialConditionLevelChange}
|
||||
theme={theme}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state: SharedAppState) {
|
||||
return {
|
||||
activeConditions: rulesEngineSelectors.getActiveConditions(state),
|
||||
ruleData: rulesEngineSelectors.getRuleData(state),
|
||||
isReadonly: appEnvSelectors.getIsReadonly(state),
|
||||
theme: rulesEngineSelectors.getCharacterTheme(state),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(ConditionManagePane);
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleHeaderContent,
|
||||
ConditionIcon,
|
||||
} from "@dndbeyond/character-components/es";
|
||||
import {
|
||||
CharacterTheme,
|
||||
ConditionContract,
|
||||
ConditionLevelUtils,
|
||||
ConditionUtils,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { HtmlContent } from "~/components/HtmlContent";
|
||||
import { ProgressBar } from "~/subApps/sheet/components/Sidebar/components/ProgressBar";
|
||||
|
||||
import ConditionLevelsTable from "../../../../components/ConditionLevelsTable";
|
||||
|
||||
interface Props {
|
||||
condition: ConditionContract;
|
||||
conditionLevel: number | null;
|
||||
isActive: boolean;
|
||||
onConditionLevelChange: (
|
||||
condition: ConditionContract,
|
||||
level: number | null
|
||||
) => void;
|
||||
isReadonly: boolean;
|
||||
theme: CharacterTheme;
|
||||
}
|
||||
export default class ConditionManagePaneSpecialCondition extends React.PureComponent<Props> {
|
||||
handleLevelChange = (newLevel: number | null): void => {
|
||||
const { onConditionLevelChange, condition } = this.props;
|
||||
|
||||
onConditionLevelChange(condition, newLevel);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { isActive, condition, conditionLevel, isReadonly, theme } =
|
||||
this.props;
|
||||
|
||||
let classNames: Array<string> = ["ct-condition-manage-pane__condition"];
|
||||
if (isActive) {
|
||||
classNames.push("ct-condition-manage-pane__condition--active");
|
||||
}
|
||||
|
||||
const level: React.ReactNode =
|
||||
conditionLevel !== null ? conditionLevel : "--";
|
||||
const name = ConditionUtils.getName(condition);
|
||||
|
||||
const headingNode: React.ReactNode = (
|
||||
<div className="ct-condition-manage-pane__condition-heading">
|
||||
<div className={classNames.join(" ")}>
|
||||
<div className="ct-condition-manage-pane__condition-preview">
|
||||
<ConditionIcon
|
||||
conditionType={ConditionUtils.getId(condition)}
|
||||
isDarkMode={theme.isDarkMode}
|
||||
/>
|
||||
</div>
|
||||
<div className="ct-condition-manage-pane__condition-name">{name}</div>
|
||||
<div className="ct-condition-manage-pane__condition-level">
|
||||
Level {level}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
//`
|
||||
|
||||
const headerNode: React.ReactNode = (
|
||||
<CollapsibleHeaderContent heading={headingNode} />
|
||||
);
|
||||
|
||||
const levels = ConditionUtils.getDefinitionLevels(condition);
|
||||
let levelNumbers = levels.map((level) =>
|
||||
ConditionLevelUtils.getLevel(level)
|
||||
);
|
||||
const levelEffectLookup = ConditionUtils.getLevelEffectLookup(condition);
|
||||
|
||||
const headerFooterNode: React.ReactNode = (
|
||||
<ProgressBar
|
||||
options={levelNumbers}
|
||||
value={conditionLevel}
|
||||
onClick={this.handleLevelChange}
|
||||
isInteractive={!isReadonly}
|
||||
/>
|
||||
);
|
||||
|
||||
const description = ConditionUtils.getDescription(condition);
|
||||
|
||||
return (
|
||||
<div key={ConditionUtils.getUniqueKey(condition)}>
|
||||
<Collapsible
|
||||
layoutType={"minimal"}
|
||||
header={headerNode}
|
||||
headerFooter={headerFooterNode}
|
||||
>
|
||||
<div className="ct-condition-manage-pane__condition-content">
|
||||
<HtmlContent
|
||||
className="ct-condition-manage-pane__condition-description"
|
||||
html={description ? description : ""}
|
||||
withoutTooltips
|
||||
/>
|
||||
<ConditionLevelsTable
|
||||
conditionName={name}
|
||||
levels={levelNumbers}
|
||||
activeLevel={conditionLevel}
|
||||
isInteractive={!isReadonly}
|
||||
onLevelChange={this.handleLevelChange}
|
||||
levelEffectLookup={levelEffectLookup}
|
||||
/>
|
||||
</div>
|
||||
</Collapsible>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import ConditionManagePaneSpecialCondition from "./ConditionManagePaneSpecialCondition";
|
||||
|
||||
export default ConditionManagePaneSpecialCondition;
|
||||
export { ConditionManagePaneSpecialCondition };
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
CharacterTheme,
|
||||
Condition,
|
||||
ConditionContract,
|
||||
ConditionUtils,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import ConditionManagePaneSpecialCondition from "../ConditionManagePaneSpecialCondition";
|
||||
|
||||
interface Props {
|
||||
specialConditions: Array<ConditionContract>;
|
||||
activeConditions: Array<Condition>;
|
||||
isReadonly: boolean;
|
||||
onConditionLevelChange: (
|
||||
condition: ConditionContract,
|
||||
level: number | null
|
||||
) => void;
|
||||
theme: CharacterTheme;
|
||||
}
|
||||
export default class ConditionManagePaneSpecialConditions extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const {
|
||||
specialConditions,
|
||||
activeConditions,
|
||||
isReadonly,
|
||||
onConditionLevelChange,
|
||||
theme,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{specialConditions.map((condition) => {
|
||||
let activeCondition = activeConditions.find(
|
||||
(activeCondition) =>
|
||||
ConditionUtils.getId(activeCondition) ===
|
||||
ConditionUtils.getId(condition)
|
||||
);
|
||||
let conditionLevel: number | null = activeCondition
|
||||
? ConditionUtils.getActiveLevel(activeCondition)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<ConditionManagePaneSpecialCondition
|
||||
key={ConditionUtils.getUniqueKey(condition)}
|
||||
isActive={!!activeCondition}
|
||||
condition={condition}
|
||||
onConditionLevelChange={onConditionLevelChange}
|
||||
conditionLevel={conditionLevel}
|
||||
isReadonly={isReadonly}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import ConditionManagePaneSpecialConditions from "./ConditionManagePaneSpecialConditions";
|
||||
|
||||
export default ConditionManagePaneSpecialConditions;
|
||||
export { ConditionManagePaneSpecialConditions };
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleHeaderContent,
|
||||
} from "@dndbeyond/character-components/es";
|
||||
import {
|
||||
CharacterTheme,
|
||||
ConditionContract,
|
||||
ConditionUtils,
|
||||
FormatUtils,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { HtmlContent } from "~/components/HtmlContent";
|
||||
import { Toggle } from "~/components/Toggle";
|
||||
import ConditionIcon from "~/tools/js/smartComponents/Icons/ConditionIcon";
|
||||
|
||||
interface Props {
|
||||
condition: ConditionContract;
|
||||
isActive: boolean;
|
||||
onConditionToggle: (condition: ConditionContract, isEnabled: boolean) => void;
|
||||
isReadonly: boolean;
|
||||
theme: CharacterTheme;
|
||||
}
|
||||
export default class ConditionManagePaneStandardCondition extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { isActive, condition, onConditionToggle, isReadonly, theme } =
|
||||
this.props;
|
||||
|
||||
let classNames: Array<string> = ["ct-condition-manage-pane__condition"];
|
||||
if (isActive) {
|
||||
classNames.push("ct-condition-manage-pane__condition--active");
|
||||
}
|
||||
|
||||
const name = ConditionUtils.getName(condition);
|
||||
const id = ConditionUtils.getId(condition);
|
||||
|
||||
const headingNode: React.ReactNode = (
|
||||
<div className="ct-condition-manage-pane__condition-heading">
|
||||
<div className={classNames.join(" ")}>
|
||||
<div className="ct-condition-manage-pane__condition-preview">
|
||||
<ConditionIcon conditionType={id} isDarkMode={theme.isDarkMode} />
|
||||
</div>
|
||||
<div className="ct-condition-manage-pane__condition-name">{name}</div>
|
||||
<div className="ct-condition-manage-pane__condition-toggle">
|
||||
<Toggle
|
||||
checked={isActive}
|
||||
onClick={onConditionToggle.bind(this, condition)}
|
||||
color="themed"
|
||||
aria-label={`Enable ${name}`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
//`
|
||||
const headerNode: React.ReactNode = (
|
||||
<CollapsibleHeaderContent heading={headingNode} />
|
||||
);
|
||||
|
||||
const description = ConditionUtils.getDescription(condition);
|
||||
|
||||
return (
|
||||
<Collapsible
|
||||
layoutType={"minimal"}
|
||||
header={headerNode}
|
||||
key={ConditionUtils.getUniqueKey(condition)}
|
||||
>
|
||||
<div className="ct-condition-manage-pane__condition-content">
|
||||
<HtmlContent
|
||||
className="ct-condition-manage-pane__condition-description"
|
||||
html={description ? description : ""}
|
||||
withoutTooltips
|
||||
/>
|
||||
</div>
|
||||
</Collapsible>
|
||||
);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import ConditionManagePaneStandardCondition from "./ConditionManagePaneStandardCondition";
|
||||
|
||||
export default ConditionManagePaneStandardCondition;
|
||||
export { ConditionManagePaneStandardCondition };
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
CharacterTheme,
|
||||
ConditionContract,
|
||||
ConditionUtils,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import ConditionManagePaneStandardCondition from "../ConditionManagePaneStandardCondition";
|
||||
|
||||
interface Props {
|
||||
standardConditions: Array<ConditionContract>;
|
||||
activeConditionIds: Array<number>;
|
||||
onConditionToggle: (condition: ConditionContract, isEnabled: boolean) => void;
|
||||
isReadonly: boolean;
|
||||
theme: CharacterTheme;
|
||||
}
|
||||
export default class ConditionManagePaneStandardConditions extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const {
|
||||
standardConditions,
|
||||
activeConditionIds,
|
||||
onConditionToggle,
|
||||
isReadonly,
|
||||
theme,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{standardConditions.map((condition) => {
|
||||
let isActive = activeConditionIds.includes(
|
||||
ConditionUtils.getId(condition)
|
||||
);
|
||||
|
||||
return (
|
||||
<ConditionManagePaneStandardCondition
|
||||
key={ConditionUtils.getUniqueKey(condition)}
|
||||
isActive={isActive}
|
||||
condition={condition}
|
||||
onConditionToggle={onConditionToggle}
|
||||
isReadonly={isReadonly}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import ConditionManagePaneStandardConditions from "./ConditionManagePaneStandardConditions";
|
||||
|
||||
export default ConditionManagePaneStandardConditions;
|
||||
export { ConditionManagePaneStandardConditions };
|
||||
@@ -0,0 +1,14 @@
|
||||
import ConditionManagePane from "./ConditionManagePane";
|
||||
import ConditionManagePaneSpecialCondition from "./ConditionManagePaneSpecialCondition";
|
||||
import ConditionManagePaneSpecialConditions from "./ConditionManagePaneSpecialConditions";
|
||||
import ConditionManagePaneStandardCondition from "./ConditionManagePaneStandardCondition";
|
||||
import ConditionManagePaneStandardConditions from "./ConditionManagePaneStandardConditions";
|
||||
|
||||
export default ConditionManagePane;
|
||||
export {
|
||||
ConditionManagePane,
|
||||
ConditionManagePaneSpecialCondition,
|
||||
ConditionManagePaneSpecialConditions,
|
||||
ConditionManagePaneStandardCondition,
|
||||
ConditionManagePaneStandardConditions,
|
||||
};
|
||||
Reference in New Issue
Block a user