New source found from dndbeyond.com
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import { RollRequest } from "@dndbeyond/dice";
|
||||
import { RollDicePayload } from "@dndbeyond/pocket-dimension-dice/types";
|
||||
|
||||
import LoadingPlaceholder from "../../LoadingPlaceholder";
|
||||
import { DataLoadingStatusEnum } from "../../componentConstants";
|
||||
@@ -14,7 +14,7 @@ export interface DiceRollProps {
|
||||
rollKey: string;
|
||||
nextRollKey: string | null;
|
||||
rollTotal: number | null;
|
||||
diceRollRequest: RollRequest;
|
||||
diceRollRequest: RollDicePayload["data"];
|
||||
onChange?: (
|
||||
key: string,
|
||||
newValue: string | null,
|
||||
@@ -25,7 +25,7 @@ export interface DiceRollProps {
|
||||
) => void;
|
||||
onRoll: (
|
||||
key: string,
|
||||
diceRollRequest: RollRequest,
|
||||
diceRollRequest: RollDicePayload["data"],
|
||||
nextRollKey: string | null
|
||||
) => void;
|
||||
rollValues: DiceRollValuesProps["rollValues"];
|
||||
@@ -87,7 +87,7 @@ const DiceRoll: React.FunctionComponent<DiceRollProps> = ({
|
||||
}
|
||||
|
||||
contentNode = (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<div className={diceTotalClassNames.join(" ")}>
|
||||
<label className="ddbc-dice-roll__total-label" htmlFor={rollKey}>
|
||||
{rollTotal ?? "--"}
|
||||
@@ -107,7 +107,7 @@ const DiceRoll: React.FunctionComponent<DiceRollProps> = ({
|
||||
rollButtonText={rollButtonText}
|
||||
selectPlaceholderText={selectPlaceholderText}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</>
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
+6
-2
@@ -2,9 +2,11 @@ import React from "react";
|
||||
|
||||
import { HtmlSelectOption } from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { Select } from "~/components/Select";
|
||||
|
||||
import { DataLoadingStatusEnum } from "../../../componentConstants";
|
||||
import { Button } from "../../../legacy/Button";
|
||||
import { Select } from "../../../legacy/Select";
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
export interface DiceRollActionNodeProps {
|
||||
rollKey: string;
|
||||
@@ -15,7 +17,7 @@ export interface DiceRollActionNodeProps {
|
||||
rollButtonText?: string;
|
||||
selectPlaceholderText?: string;
|
||||
onRoll: () => void;
|
||||
onChange?: (newValue: string | null) => void;
|
||||
onChange?: (newValue: string | number) => void;
|
||||
}
|
||||
const DiceRollActionNode: React.FunctionComponent<DiceRollActionNodeProps> = ({
|
||||
rollKey,
|
||||
@@ -31,11 +33,13 @@ const DiceRollActionNode: React.FunctionComponent<DiceRollActionNodeProps> = ({
|
||||
if (options?.length && rollTotal !== null) {
|
||||
return (
|
||||
<Select
|
||||
className={styles.select}
|
||||
id={rollKey}
|
||||
value={assignedValue}
|
||||
options={options}
|
||||
placeholder={selectPlaceholderText}
|
||||
onChange={onChange}
|
||||
name={rollKey}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import DiceRollActionNode from "./DiceRollActionNode";
|
||||
|
||||
//Props typings
|
||||
export * from "./DiceRollActionNode";
|
||||
|
||||
export { DiceRollActionNode };
|
||||
|
||||
export default DiceRollActionNode;
|
||||
+2
-2
@@ -40,7 +40,7 @@ const DiceRollValues: React.FunctionComponent<DiceRollValuesProps> = ({
|
||||
const classNames: Array<string> = ["ddbc-dice-roll__dice-value"];
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<>
|
||||
{orderedKeptDiceValues.map((rollValue: RollValueContract, idx) => {
|
||||
return (
|
||||
<div key={idx} className={classNames.join(" ")}>
|
||||
@@ -57,7 +57,7 @@ const DiceRollValues: React.FunctionComponent<DiceRollValuesProps> = ({
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import DiceRollValues from "./DiceRollValues";
|
||||
|
||||
//Props typings
|
||||
export * from "./DiceRollValues";
|
||||
|
||||
export { DiceRollValues };
|
||||
|
||||
export default DiceRollValues;
|
||||
@@ -0,0 +1,10 @@
|
||||
import DiceRoll from "./DiceRoll";
|
||||
|
||||
//Props typings
|
||||
export * from "./DiceRoll";
|
||||
export * from "./DiceRollValues";
|
||||
export * from "./DiceRollActionNode";
|
||||
|
||||
export { DiceRoll };
|
||||
|
||||
export default DiceRoll;
|
||||
@@ -1,12 +1,27 @@
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import React, { useCallback, useContext, useMemo, useState } from "react";
|
||||
|
||||
import {
|
||||
CampaignUtils,
|
||||
HelperUtils,
|
||||
HtmlSelectOption,
|
||||
RollResultContract,
|
||||
RollValueContract,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
import { Dice, RollRequest } from "@dndbeyond/dice";
|
||||
import { Platform } from "@dndbeyond/event-pipeline-lib/shared";
|
||||
import {
|
||||
GameLogContext,
|
||||
isMessage,
|
||||
useMessageBroker,
|
||||
} from "@dndbeyond/game-log-components";
|
||||
import { DiceVisibilities } from "@dndbeyond/pocket-dimension-dice/constants";
|
||||
import { Context as DiceWorkerContext } from "@dndbeyond/pocket-dimension-dice/context";
|
||||
import { instrumentDiceRoll } from "@dndbeyond/pocket-dimension-dice/helpers/bi/instrumentDiceRoll";
|
||||
import { rollDice } from "@dndbeyond/pocket-dimension-dice/helpers/rollDice";
|
||||
import { useUserDiceDataStore } from "@dndbeyond/pocket-dimension-dice/hooks/useUserDiceDataStore";
|
||||
import { RollDicePayload } from "@dndbeyond/pocket-dimension-dice/types";
|
||||
|
||||
import { useAuth } from "~/contexts/Authentication";
|
||||
import { useCharacterEngine } from "~/hooks/useCharacterEngine";
|
||||
|
||||
import { DataLoadingStatusEnum } from "../componentConstants";
|
||||
import { Button, RemoveButton } from "../legacy";
|
||||
@@ -44,9 +59,7 @@ export interface DiceRollGroupProps {
|
||||
onSetRollStatus: (rollKey: string, status: DataLoadingStatusEnum) => void;
|
||||
rollStatusLookup: Record<string, DataLoadingStatusEnum>;
|
||||
options?: DiceRollProps["options"];
|
||||
diceRollRequest:
|
||||
| DiceRollProps["diceRollRequest"]
|
||||
| Array<DiceRollProps["diceRollRequest"]>;
|
||||
diceRollRequest: RollDicePayload["data"] | Array<RollDicePayload["data"]>;
|
||||
}
|
||||
const DiceRollGroup: React.FunctionComponent<DiceRollGroupProps> = ({
|
||||
className = "",
|
||||
@@ -68,6 +81,24 @@ const DiceRollGroup: React.FunctionComponent<DiceRollGroupProps> = ({
|
||||
onUpdateDiceRoll,
|
||||
rollStatusLookup,
|
||||
}) => {
|
||||
const { env, hasPddErrored, isPddReady } = useContext(DiceWorkerContext);
|
||||
const [{ userId }] = useContext(GameLogContext);
|
||||
const { campaign } = useCharacterEngine();
|
||||
const gameId = campaign ? String(campaign.id) : undefined;
|
||||
const dmId = campaign
|
||||
? String(CampaignUtils.getDmUserId(campaign))
|
||||
: undefined;
|
||||
const [groupRolls, setGroupRolls] = useState<
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
rollKey: string;
|
||||
properties: Partial<RollResultContract>;
|
||||
nextRollKey: string | null;
|
||||
}
|
||||
>
|
||||
>({});
|
||||
const user = useAuth();
|
||||
const classNames = useMemo<Array<string>>(
|
||||
() => ["ddbc-dice-roll-group", className],
|
||||
[className]
|
||||
@@ -110,8 +141,8 @@ const DiceRollGroup: React.FunctionComponent<DiceRollGroupProps> = ({
|
||||
});
|
||||
}, [options, diceRolls, exclusiveOptions, assignedValues]);
|
||||
|
||||
const generatedRollRequests = useMemo<Array<RollRequest>>(() => {
|
||||
let requests: Array<RollRequest> = [];
|
||||
const generatedRollRequests = useMemo<Array<RollDicePayload["data"]>>(() => {
|
||||
let requests: Array<RollDicePayload["data"]> = [];
|
||||
for (let i = 0; i < diceRolls.length; i++) {
|
||||
if (!Array.isArray(diceRollRequest)) {
|
||||
requests.push(diceRollRequest);
|
||||
@@ -130,50 +161,94 @@ const DiceRollGroup: React.FunctionComponent<DiceRollGroupProps> = ({
|
||||
const handleRoll = useCallback(
|
||||
(
|
||||
rollKey: string,
|
||||
diceRollRequest: RollRequest,
|
||||
diceRollRequest: RollDicePayload["data"],
|
||||
nextRollKey: string | null
|
||||
): void => {
|
||||
onSetRollStatus(rollKey, DataLoadingStatusEnum.LOADING);
|
||||
const diceNotation = `${diceRollRequest.rolls[0].diceNotation.set
|
||||
.map((set) => `${set?.count}${set?.dieType}`)
|
||||
.join("")}`;
|
||||
const { data } = rollDice(
|
||||
{
|
||||
action: diceRollRequest.action,
|
||||
diceNotation,
|
||||
entityId: String(diceRollRequest.context?.entityId),
|
||||
entityType: String(diceRollRequest.context?.entityType),
|
||||
gameId,
|
||||
rollType: diceRollRequest.rolls[0].rollType,
|
||||
setId: String(
|
||||
useUserDiceDataStore.getState().getUserDiceData(Number(userId))
|
||||
?.setId
|
||||
),
|
||||
userId,
|
||||
avatarUrl: diceRollRequest.context?.avatarUrl,
|
||||
name: diceRollRequest.context?.name,
|
||||
operand: diceRollRequest.rolls[0].diceNotation.set[0]?.operand,
|
||||
dmId,
|
||||
},
|
||||
hasPddErrored,
|
||||
isPddReady,
|
||||
(eventPayload) =>
|
||||
instrumentDiceRoll(
|
||||
user,
|
||||
eventPayload,
|
||||
Platform.Web,
|
||||
"characterBuilderRollGroup",
|
||||
campaign?.id,
|
||||
undefined,
|
||||
env
|
||||
)
|
||||
);
|
||||
|
||||
Dice.roll(diceRollRequest)
|
||||
.then((result) => {
|
||||
//RollResult | undefined - RollResult is not exported from Dice;
|
||||
// only expect to have one single rollRequest.
|
||||
const rollResult = result.rolls[0].result ?? null;
|
||||
const rollValues = DiceComponentUtils.generateRollValueContracts(data);
|
||||
|
||||
if (!rollResult) {
|
||||
throw new Error("error in rollResult");
|
||||
}
|
||||
if (!rollValues) {
|
||||
throw new Error("error in rollResult values");
|
||||
}
|
||||
|
||||
const rollValues =
|
||||
DiceComponentUtils.generateRollValueContracts(result);
|
||||
const newGroupRoll = {
|
||||
rollKey,
|
||||
properties: {
|
||||
rollValues,
|
||||
rollTotal: data.rolls[0].result?.total,
|
||||
},
|
||||
nextRollKey,
|
||||
};
|
||||
|
||||
if (!rollValues) {
|
||||
throw new Error("error in rollResult values");
|
||||
}
|
||||
setGroupRolls((prevState) => ({
|
||||
...prevState,
|
||||
[String(data?.rollId)]: newGroupRoll,
|
||||
}));
|
||||
|
||||
//update status
|
||||
onSetRollStatus(rollKey, DataLoadingStatusEnum.LOADED);
|
||||
if (
|
||||
data.rollId &&
|
||||
useUserDiceDataStore.getState().getUserDiceData(Number(userId))
|
||||
?.settings.visibility === DiceVisibilities.Disabled
|
||||
) {
|
||||
//update status
|
||||
onSetRollStatus(newGroupRoll.rollKey, DataLoadingStatusEnum.LOADED);
|
||||
|
||||
//update diceRoll
|
||||
onUpdateDiceRoll(
|
||||
rollKey,
|
||||
{ rollValues, rollTotal: rollResult.total },
|
||||
nextRollKey
|
||||
);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
//this could handle different errors types from dice package or thrown errors from result
|
||||
|
||||
onSetRollStatus(rollKey, DataLoadingStatusEnum.NOT_LOADED);
|
||||
|
||||
if (onRollError) {
|
||||
onRollError(error.message);
|
||||
}
|
||||
console.log("roll error", error);
|
||||
});
|
||||
//update diceRoll
|
||||
onUpdateDiceRoll(
|
||||
newGroupRoll.rollKey,
|
||||
newGroupRoll.properties,
|
||||
newGroupRoll.nextRollKey
|
||||
);
|
||||
} else {
|
||||
onSetRollStatus(rollKey, DataLoadingStatusEnum.LOADING);
|
||||
}
|
||||
},
|
||||
[]
|
||||
[
|
||||
campaign?.id,
|
||||
dmId,
|
||||
env,
|
||||
gameId,
|
||||
hasPddErrored,
|
||||
isPddReady,
|
||||
onSetRollStatus,
|
||||
onUpdateDiceRoll,
|
||||
user,
|
||||
userId,
|
||||
]
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
@@ -220,6 +295,32 @@ const DiceRollGroup: React.FunctionComponent<DiceRollGroupProps> = ({
|
||||
}
|
||||
}, [onRemoveGroup, groupKey, nextGroupKey]);
|
||||
|
||||
useMessageBroker(
|
||||
useCallback(
|
||||
(message) => {
|
||||
if (
|
||||
isMessage(message) &&
|
||||
message.eventType === "dice/roll/fulfilled" &&
|
||||
groupRolls[message.data.rollId]
|
||||
) {
|
||||
//update status
|
||||
onSetRollStatus(
|
||||
groupRolls[message.data.rollId].rollKey,
|
||||
DataLoadingStatusEnum.LOADED
|
||||
);
|
||||
|
||||
//update diceRoll
|
||||
onUpdateDiceRoll(
|
||||
groupRolls[message.data.rollId].rollKey,
|
||||
groupRolls[message.data.rollId].properties,
|
||||
groupRolls[message.data.rollId].nextRollKey
|
||||
);
|
||||
}
|
||||
},
|
||||
[groupRolls, onSetRollStatus, onUpdateDiceRoll]
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classNames.join(" ")}>
|
||||
<div className="ddbc-dice-roll-group__actions">
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import DiceRoll from "./DiceRoll";
|
||||
import DiceRollGroup from "./DiceRollGroup";
|
||||
|
||||
export * from "./DiceRollGroup";
|
||||
export { DiceRollGroup, DiceRoll };
|
||||
|
||||
export default DiceRollGroup;
|
||||
Reference in New Issue
Block a user