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:
2025-05-28 11:50:03 -07:00
commit 8df9031d27
3592 changed files with 319051 additions and 0 deletions
@@ -0,0 +1,244 @@
import clsx from "clsx";
import React from "react";
import { connect, DispatchProp } from "react-redux";
import {
CharacterPreferences,
SpeedInfo,
RuleData,
RuleDataUtils,
rulesEngineSelectors,
CharacterTheme,
characterSelectors,
CharacterStatusSlug,
} from "@dndbeyond/character-rules-engine/es";
import { GameLogContext } from "@dndbeyond/game-log-components";
import { NumberDisplay } from "~/components/NumberDisplay";
import { PremadeCharacterEditStatus } from "~/components/PremadeCharacterEditStatus";
import { useSidebar } from "~/contexts/Sidebar";
import { PaneInfo } from "~/contexts/Sidebar/Sidebar";
import { InitiativeBox } from "~/subApps/sheet/components/InitiativeBox";
import { PaneComponentEnum } from "~/subApps/sheet/components/Sidebar/types";
import { appEnvSelectors } from "../../../../Shared/selectors";
import { SheetAppState } from "../../../typings";
import styles from "./styles.module.css";
interface Props extends DispatchProp {
armorClass: number;
speeds: SpeedInfo;
proficiencyBonus: number;
preferences: CharacterPreferences;
ruleData: RuleData;
diceEnabled: boolean;
theme: CharacterTheme;
paneHistoryStart: PaneInfo["paneHistoryStart"];
isReadonly: boolean;
characterStatus: CharacterStatusSlug | null;
}
class CombatMobile extends React.PureComponent<Props> {
static defaultProps = {
diceEnabled: false,
};
handleProficiencyBonusClick = (evt: React.MouseEvent): void => {
const { paneHistoryStart } = this.props;
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
paneHistoryStart(PaneComponentEnum.PROFICIENCY_BONUS);
};
handleSpeedsClick = (evt: React.MouseEvent): void => {
const { paneHistoryStart } = this.props;
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
paneHistoryStart(PaneComponentEnum.SPEED_MANAGE);
};
handleDefensesSummaryClick = (evt: React.MouseEvent): void => {
const { paneHistoryStart } = this.props;
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
paneHistoryStart(PaneComponentEnum.DEFENSE_MANAGE);
};
handleConditionSummaryClick = (evt: React.MouseEvent): void => {
const { paneHistoryStart } = this.props;
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
paneHistoryStart(PaneComponentEnum.CONDITION_MANAGE);
};
handleArmorClassClick = (evt: React.MouseEvent): void => {
const { paneHistoryStart } = this.props;
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
paneHistoryStart(PaneComponentEnum.ARMOR_MANAGE);
};
handleInitiativeClick = (evt: React.MouseEvent): void => {
const { paneHistoryStart } = this.props;
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
paneHistoryStart(PaneComponentEnum.INITIATIVE);
};
renderProficiency = (): React.ReactNode => {
const { proficiencyBonus } = this.props;
return (
<div
className="ct-combat-mobile__extra ct-combat-mobile__extra--proficiency"
onClick={this.handleProficiencyBonusClick}
>
<div className="ct-combat-mobile__extra-heading">
<div className="ct-combat-mobile__extra-label">Proficiency</div>
</div>
<div className="ct-combat-mobile__extra-value">
<NumberDisplay
type="signed"
number={proficiencyBonus}
size={"large"}
className={clsx([
!this.props.theme.isDarkMode && styles.numberColorOverride,
])}
/>
</div>
<div className="ct-combat-mobile__extra-footer">
<div className="ct-combat-mobile__extra-label">Bonus</div>
</div>
</div>
);
};
renderSpeed = (): React.ReactNode => {
const { preferences, speeds, ruleData, theme } = this.props;
const displaySpeedValue: number =
speeds[
RuleDataUtils.getSpeedMovementKeyById(preferences.primaryMovement)
];
const displaySpeedLabel = RuleDataUtils.getMovementDescription(
preferences.primaryMovement,
ruleData
);
return (
<div
className="ct-combat-mobile__extra ct-combat-mobile__extra--speed"
onClick={this.handleSpeedsClick}
>
<div className="ct-combat-mobile__extra-heading">
<div className="ct-combat-mobile__extra-subheading">
{displaySpeedLabel}
</div>
</div>
<div className="ct-combat-mobile__extra-value">
<NumberDisplay
type="distanceInFt"
number={displaySpeedValue}
size={"large"}
className={clsx([
!this.props.theme.isDarkMode && styles.numberColorOverride,
])}
/>
</div>
<div className="ct-combat-mobile__extra-footer">
<div className="ct-combat-mobile__extra-label">Speed</div>
</div>
</div>
);
};
renderArmorClass = (): React.ReactNode => {
const { armorClass } = this.props;
return (
<div
className="ct-combat-mobile__extra ct-combat-mobile__extra--ac"
onClick={this.handleArmorClassClick}
>
<div className="ct-combat-mobile__extra-heading">
<div className="ct-combat-mobile__extra-label">Armor</div>
</div>
<div
className="ct-combat-mobile__extra-value"
data-testid="armor-class-value"
>
{armorClass}
</div>
<div className="ct-combat-mobile__extra-footer">
<div className="ct-combat-mobile__extra-label">Class</div>
</div>
</div>
);
};
render() {
const { theme, isReadonly, characterStatus } = this.props;
return (
<div
className={`ct-combat-mobile ${
theme.isDarkMode ? "ct-combat-mobile--dark-mode" : ""
}`}
>
<div className="ct-combat-mobile__extras">
{this.renderProficiency()}
{this.renderSpeed()}
<InitiativeBox isMobile={true} />
{this.renderArmorClass()}
<div className="ct-combat-mobile__extra ct-combat-mobile__extra--statuses">
<div className="ct-combat-mobile__ctas">
<div className="ct-combat-mobile__cta">
<div
className="ct-combat-mobile__cta-button"
onClick={this.handleDefensesSummaryClick}
>
Defenses
</div>
</div>
<div className="ct-combat-mobile__cta">
<div
className="ct-combat-mobile__cta-button"
onClick={this.handleConditionSummaryClick}
>
Conditions
</div>
</div>
</div>
</div>
</div>
<PremadeCharacterEditStatus
characterStatus={characterStatus}
isReadonly={isReadonly}
/>
</div>
);
}
}
function mapStateToProps(state: SheetAppState) {
return {
armorClass: rulesEngineSelectors.getAcTotal(state),
proficiencyBonus: rulesEngineSelectors.getProficiencyBonus(state),
speeds: rulesEngineSelectors.getCurrentCarriedWeightSpeed(state),
preferences: rulesEngineSelectors.getCharacterPreferences(state),
ruleData: rulesEngineSelectors.getRuleData(state),
diceEnabled: appEnvSelectors.getDiceEnabled(state),
theme: rulesEngineSelectors.getCharacterTheme(state),
characterStatus: characterSelectors.getStatusSlug(state),
isReadonly: appEnvSelectors.getIsReadonly(state),
};
}
const CombatMobileContainer = (props) => {
const {
pane: { paneHistoryStart },
} = useSidebar();
return <CombatMobile {...props} paneHistoryStart={paneHistoryStart} />;
};
CombatMobileContainer.contextType = GameLogContext;
export default connect(mapStateToProps)(CombatMobileContainer);
@@ -0,0 +1,4 @@
import CombatMobile from "./CombatMobile";
export default CombatMobile;
export { CombatMobile };