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:
@@ -0,0 +1,356 @@
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined";
|
||||
import {
|
||||
Box,
|
||||
Checkbox,
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
FormLabel,
|
||||
Grid,
|
||||
IconButton,
|
||||
Modal,
|
||||
Paper,
|
||||
Stack,
|
||||
ToggleButton,
|
||||
ToggleButtonGroup,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import clsx from "clsx";
|
||||
import { useContext } from "react";
|
||||
|
||||
import { RuleDataUtils } from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { SourceCategoryDescription } from "~/constants";
|
||||
import { useFeatureFlags } from "~/contexts/FeatureFlag";
|
||||
import { generateCharacterPreferences } from "~/helpers/generateCharacterPreferences";
|
||||
import PreferenceUpdateLocation from "~/tools/js/Shared/constants/PreferenceUpdateLocation";
|
||||
|
||||
import {
|
||||
CheckboxInfo,
|
||||
FormCheckBoxesField,
|
||||
} from "../../Shared/components/common/FormCheckBoxesField";
|
||||
import AbilitySummary from "../AbilitySummary";
|
||||
import PrivacyTypeRadio from "../PrivacyTypeRadio";
|
||||
import { UserPreferenceContext } from "../UserPreference";
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
interface CharacterSettingsModalProps {
|
||||
open: boolean;
|
||||
updateLocation: PreferenceUpdateLocation;
|
||||
handleClose: () => void;
|
||||
}
|
||||
|
||||
const CharacterSettingsModal = ({
|
||||
open,
|
||||
updateLocation,
|
||||
handleClose,
|
||||
}: CharacterSettingsModalProps) => {
|
||||
const {
|
||||
privacyType,
|
||||
isDarkModeEnabled,
|
||||
abilityScoreDisplayType,
|
||||
updatePreferences,
|
||||
ruleData,
|
||||
defaultEnabledSourceCategories,
|
||||
isHomebrewEnabled,
|
||||
} = useContext(UserPreferenceContext);
|
||||
|
||||
const { featureFlags } = useFeatureFlags();
|
||||
|
||||
const preferences = generateCharacterPreferences(featureFlags);
|
||||
|
||||
const getTheme = (darkMode: boolean) => ({
|
||||
name: "DDB Red",
|
||||
backgroundColor: darkMode ? "#10161ADB" : "#FEFEFE",
|
||||
isDefault: true,
|
||||
themeColor: "#C53131",
|
||||
themeColorId: null,
|
||||
isDarkMode: darkMode || false,
|
||||
});
|
||||
|
||||
const rollContext = {
|
||||
entityId: "52962664",
|
||||
entityType: "character",
|
||||
name: "Stor Hornraven",
|
||||
avatarUrl:
|
||||
"https://stg.dndbeyond.com/avatars/18589/680/1581111423-52962664.jpeg?width=150&height=150&fit=crop&quality=95&auto=webp",
|
||||
};
|
||||
|
||||
const handleSourceCategoryChange = (
|
||||
sourceId: number,
|
||||
isActive: boolean
|
||||
): void => {
|
||||
const newSourceCategories = {
|
||||
...defaultEnabledSourceCategories,
|
||||
[sourceId]: isActive,
|
||||
};
|
||||
|
||||
updatePreferences({
|
||||
privacyType,
|
||||
isDarkModeEnabled,
|
||||
abilityScoreDisplayType,
|
||||
updateLocation,
|
||||
defaultEnabledSourceCategories: newSourceCategories,
|
||||
isHomebrewEnabled,
|
||||
});
|
||||
};
|
||||
|
||||
let sourceToggles: Array<CheckboxInfo> = [];
|
||||
let partneredSourceCheckboxes: Array<CheckboxInfo> = [];
|
||||
let allPartneredSources: Array<number> = [];
|
||||
|
||||
if (ruleData) {
|
||||
const activeSourceCategories = Object.keys(defaultEnabledSourceCategories)
|
||||
.filter((key) => defaultEnabledSourceCategories[key])
|
||||
.map(Number);
|
||||
RuleDataUtils.getSourceCategories(ruleData).forEach((sourceCategory) => {
|
||||
if (!sourceCategory.isToggleable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const checkbox: CheckboxInfo = {
|
||||
label: `${sourceCategory.name}`,
|
||||
initiallyEnabled: activeSourceCategories.includes(sourceCategory.id),
|
||||
onChange: handleSourceCategoryChange.bind(this, sourceCategory.id),
|
||||
sortOrder: sourceCategory.sortOrder,
|
||||
description: sourceCategory.description ?? "",
|
||||
};
|
||||
|
||||
if (sourceCategory.isPartneredContent) {
|
||||
delete checkbox.description;
|
||||
partneredSourceCheckboxes.push(checkbox);
|
||||
allPartneredSources.push(sourceCategory.id);
|
||||
} else {
|
||||
sourceToggles.push(checkbox);
|
||||
}
|
||||
});
|
||||
|
||||
//Add Homebrew to sources for display
|
||||
sourceToggles.push({
|
||||
label: "Homebrew",
|
||||
initiallyEnabled: isHomebrewEnabled,
|
||||
description: SourceCategoryDescription.homebrew,
|
||||
onChange: (isActive: boolean) => {
|
||||
updatePreferences({
|
||||
privacyType,
|
||||
isDarkModeEnabled,
|
||||
abilityScoreDisplayType,
|
||||
updateLocation,
|
||||
defaultEnabledSourceCategories,
|
||||
isHomebrewEnabled: isActive,
|
||||
});
|
||||
},
|
||||
|
||||
sortOrder: 0,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
className={clsx(styles.modal)}
|
||||
aria-labelledby="modal-modal-title"
|
||||
aria-describedby="modal-modal-description"
|
||||
>
|
||||
<Paper className={clsx(styles.content)}>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
style={{ padding: 16, borderBottom: "1px solid #A2ACB2" }}
|
||||
>
|
||||
<SettingsOutlinedIcon
|
||||
style={{
|
||||
color: "rgba(0,0,0,0.54)",
|
||||
marginRight: 5,
|
||||
height: 22,
|
||||
width: 22,
|
||||
}}
|
||||
/>
|
||||
<label className={clsx(styles.modalTitle)}>
|
||||
Default Character Settings
|
||||
</label>
|
||||
<IconButton
|
||||
aria-label="close"
|
||||
onClick={handleClose}
|
||||
size="small"
|
||||
style={{
|
||||
marginLeft: "auto",
|
||||
color: "rgba(0,0,0,0.54)",
|
||||
}}
|
||||
>
|
||||
<CloseIcon style={{ width: 20 }} />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
<Box style={{ padding: 16 }}>
|
||||
<label className={clsx(styles.modalDescription)}>
|
||||
These settings apply defaults to all new Characters you create. Any
|
||||
settings you apply to a specific Character will override the choices
|
||||
you make here.
|
||||
</label>
|
||||
|
||||
<>
|
||||
<FormCheckBoxesField
|
||||
heading="Sources"
|
||||
description={SourceCategoryDescription.official}
|
||||
checkboxes={sourceToggles}
|
||||
showAccordion={false}
|
||||
/>
|
||||
|
||||
<FormCheckBoxesField
|
||||
heading="Partnered Content"
|
||||
description={SourceCategoryDescription.partnered}
|
||||
checkboxes={partneredSourceCheckboxes}
|
||||
checkUncheckAllEnabled={true}
|
||||
showAccordion={false}
|
||||
accordionHeading="Choose Partners"
|
||||
allText="All"
|
||||
/>
|
||||
</>
|
||||
|
||||
<PrivacyTypeRadio
|
||||
color="info"
|
||||
initialValue={privacyType}
|
||||
handleChange={(e) =>
|
||||
updatePreferences({
|
||||
isDarkModeEnabled,
|
||||
abilityScoreDisplayType,
|
||||
updateLocation,
|
||||
privacyType: parseInt(e.target.value),
|
||||
defaultEnabledSourceCategories,
|
||||
isHomebrewEnabled,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<p
|
||||
style={{
|
||||
color: "#000",
|
||||
fontSize: 16,
|
||||
fontWeight: 700,
|
||||
letterSpacing: -0.5,
|
||||
textTransform: "uppercase",
|
||||
margin: "19px 0 0",
|
||||
padding: "10px 0",
|
||||
}}
|
||||
>
|
||||
Display
|
||||
</p>
|
||||
<Grid container>
|
||||
<Grid item xs={12} md={8}>
|
||||
<FormControl>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
color="info"
|
||||
checked={isDarkModeEnabled}
|
||||
onChange={(e) =>
|
||||
updatePreferences({
|
||||
privacyType,
|
||||
abilityScoreDisplayType,
|
||||
updateLocation,
|
||||
isDarkModeEnabled: e.target.checked,
|
||||
defaultEnabledSourceCategories,
|
||||
isHomebrewEnabled,
|
||||
})
|
||||
}
|
||||
style={{ paddingTop: 0 }}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<>
|
||||
<p style={{ margin: 0, fontSize: 14 }}>Underdark Mode</p>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "grey.500",
|
||||
margin: 0,
|
||||
fontSize: 12,
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
Activate dark mode for Character Sheets.
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
sx={{ display: "flex", alignItems: "flex-start" }}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl style={{ marginTop: 24 }}>
|
||||
<FormLabel>
|
||||
<p style={{ margin: 0, fontSize: 14, color: "#000" }}>
|
||||
Ability Scores / Modifiers
|
||||
</p>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "grey.500",
|
||||
margin: "0 0 16px",
|
||||
fontSize: 12,
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
Reverse the display of Ability Scores and Modifiers.{" "}
|
||||
</Typography>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<ToggleButtonGroup
|
||||
color="info"
|
||||
value={abilityScoreDisplayType}
|
||||
exclusive
|
||||
onChange={(e, value) => {
|
||||
if (value !== null)
|
||||
updatePreferences({
|
||||
privacyType,
|
||||
isDarkModeEnabled,
|
||||
updateLocation,
|
||||
abilityScoreDisplayType: value,
|
||||
defaultEnabledSourceCategories,
|
||||
isHomebrewEnabled,
|
||||
});
|
||||
}}
|
||||
aria-label="Platform"
|
||||
>
|
||||
<ToggleButton value={2}>Modifiers Top</ToggleButton>
|
||||
<ToggleButton value={1}>Scores Top</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</FormControl>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
md={4}
|
||||
display="flex"
|
||||
alignItems="flex-start"
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: "grey.50",
|
||||
border: "1px solid transparent",
|
||||
borderColor: "grey.200",
|
||||
borderRadius: 1,
|
||||
display: "inline-block",
|
||||
py: 1,
|
||||
px: 2,
|
||||
}}
|
||||
>
|
||||
<p style={{ textAlign: "center", marginBottom: 4 }}>Preview</p>
|
||||
<AbilitySummary
|
||||
ability={{ name: "Strength", score: 14, modifier: 2 }}
|
||||
preferences={{
|
||||
...preferences,
|
||||
abilityScoreDisplayType: abilityScoreDisplayType,
|
||||
}}
|
||||
theme={getTheme(isDarkModeEnabled || false)}
|
||||
onClick={(e) => e.getBaseScore()}
|
||||
rollContext={rollContext}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CharacterSettingsModal;
|
||||
@@ -0,0 +1,4 @@
|
||||
import CharacterSettingsModal from "./CharacterSettingsModal";
|
||||
|
||||
export default CharacterSettingsModal;
|
||||
export { CharacterSettingsModal };
|
||||
Reference in New Issue
Block a user