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:
+69
@@ -0,0 +1,69 @@
|
||||
import clsx from "clsx";
|
||||
import { FC, HTMLAttributes } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import { CharacterAvatarPortrait } from "@dndbeyond/character-components/es";
|
||||
|
||||
import { useCharacterTheme } from "~/contexts/CharacterTheme";
|
||||
import { appEnvSelectors } from "~/tools/js/Shared/selectors";
|
||||
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
/*
|
||||
This is a single character in the CampaignPane. It displays the character's avatar, name, and user name.
|
||||
|
||||
*/
|
||||
|
||||
export interface CampaignCharacterProps extends HTMLAttributes<HTMLDivElement> {
|
||||
characterId: number;
|
||||
avatarUrl: string;
|
||||
characterName: string;
|
||||
userName: string;
|
||||
}
|
||||
|
||||
export const CampaignCharacter: FC<CampaignCharacterProps> = ({
|
||||
characterId,
|
||||
avatarUrl,
|
||||
characterName,
|
||||
userName,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
const { isDarkMode } = useCharacterTheme();
|
||||
const currentCharacterId = useSelector(appEnvSelectors.getCharacterId);
|
||||
const isCurrentCharacter = currentCharacterId === characterId;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx([
|
||||
styles.character,
|
||||
isCurrentCharacter && styles.current,
|
||||
className,
|
||||
])}
|
||||
key={characterId}
|
||||
{...props}
|
||||
>
|
||||
<CharacterAvatarPortrait
|
||||
className={styles.preview}
|
||||
avatarUrl={avatarUrl}
|
||||
/>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.name}>
|
||||
{isCurrentCharacter ? (
|
||||
<span>{characterName}</span>
|
||||
) : (
|
||||
<a
|
||||
href={`/characters/${characterId}`}
|
||||
className={clsx([styles.link, isDarkMode && styles.darkMode])}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{characterName}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.user}>{userName}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
import { FC, HTMLAttributes } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import {
|
||||
DarkPlayButtonSvg,
|
||||
LightPlayButtonSvg,
|
||||
} from "@dndbeyond/character-components/es";
|
||||
|
||||
import { Button } from "~/components/Button/Button";
|
||||
import { HtmlContent } from "~/components/HtmlContent";
|
||||
import { PreferencePrivacyTypeEnum } from "~/constants";
|
||||
import { useCharacterTheme } from "~/contexts/CharacterTheme";
|
||||
import { useCharacterEngine } from "~/hooks/useCharacterEngine";
|
||||
import { Header } from "~/subApps/sheet/components/Sidebar/components/Header";
|
||||
import { PaneInitFailureContent } from "~/subApps/sheet/components/Sidebar/components/PaneInitFailureContent";
|
||||
import { appEnvSelectors } from "~/tools/js/Shared/selectors";
|
||||
import { NavigationUtils } from "~/tools/js/Shared/utils";
|
||||
import { CampaignCharacterContract } from "~/types";
|
||||
|
||||
import { CampaignCharacter } from "./CampaignCharacter";
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
/*
|
||||
This is the Sidebar for a Campaign. If the character has joined a Campaign, you can click on the campaign button in the Character Sheet header to see this Sidebar. It displays the Campaign name, maps link, DM, and all characters in the campaign. If the character is the DM, they will see all characters in the campaign. If the character is not the DM, they will only see characters that have been set to public or campaign only.
|
||||
*/
|
||||
|
||||
interface CampaignPaneProps extends HTMLAttributes<HTMLDivElement> {}
|
||||
export const CampaignPane: FC<CampaignPaneProps> = ({ ...props }) => {
|
||||
const { campaign, campaignUtils } = useCharacterEngine();
|
||||
const { isDarkMode } = useCharacterTheme();
|
||||
const isReadonly = useSelector(appEnvSelectors.getIsReadonly);
|
||||
|
||||
if (!campaign) {
|
||||
return <PaneInitFailureContent />;
|
||||
}
|
||||
|
||||
const characters = campaignUtils.getCharacters(campaign);
|
||||
const description = campaignUtils.getDescription(campaign);
|
||||
|
||||
const filteredCharacters = characters
|
||||
? characters.filter(
|
||||
(character) =>
|
||||
character.privacyType === PreferencePrivacyTypeEnum.PUBLIC ||
|
||||
character.privacyType === PreferencePrivacyTypeEnum.CAMPAIGN_ONLY
|
||||
)
|
||||
: [];
|
||||
|
||||
const orderedCharacters = filteredCharacters.sort((a, b) =>
|
||||
(a.characterName ?? "").localeCompare(b.characterName ?? "")
|
||||
);
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
<div className={styles.header}>
|
||||
<Header>Campaign</Header>
|
||||
<Button
|
||||
href={NavigationUtils.getLaunchGameUrl(campaign)}
|
||||
target="_blank"
|
||||
size="x-small"
|
||||
variant="text"
|
||||
className={styles.launchButton}
|
||||
themed
|
||||
>
|
||||
{isDarkMode ? <LightPlayButtonSvg /> : <DarkPlayButtonSvg />}
|
||||
<span>Launch Game</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.name}>
|
||||
{isReadonly ? (
|
||||
campaignUtils.getName(campaign)
|
||||
) : (
|
||||
<a
|
||||
className={styles.link}
|
||||
href={campaignUtils.getLink(campaign) ?? ""}
|
||||
>
|
||||
{campaignUtils.getName(campaign)}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
{!isReadonly && description !== null && (
|
||||
<HtmlContent html={description} withoutTooltips />
|
||||
)}
|
||||
<div className={styles.dm}>
|
||||
<span className={styles.dmLabel}>DM:</span>
|
||||
<span>{campaignUtils.getDmUsername(campaign)}</span>
|
||||
</div>
|
||||
<div className={styles.characters}>
|
||||
{orderedCharacters.map((character: CampaignCharacterContract) => (
|
||||
<CampaignCharacter
|
||||
key={character.characterId}
|
||||
characterId={character.characterId}
|
||||
avatarUrl={character.avatarUrl ?? ""}
|
||||
characterName={character.characterName ?? ""}
|
||||
userName={character.username ?? ""}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user