import clsx from "clsx"; import { FC, useCallback, useContext, useEffect, useState } from "react"; import { GameLogContext, isMessage, useAwaitMessageBroker, } from "@dndbeyond/game-log-components"; import type { AnyMessage } from "@dndbeyond/message-broker-lib"; import { Rollable } from "@dndbeyond/pocket-dimension-dice/components/Rollable"; import type { RollableProps } from "@dndbeyond/pocket-dimension-dice/components/Rollable"; import "@dndbeyond/pocket-dimension-dice/components/Rollable/index.css"; import { RollDicePayload } from "@dndbeyond/pocket-dimension-dice/types"; export interface DigitalDiceWrapperProps extends Omit { rollCallback?: (rollData: RollDicePayload["data"]) => void; isDiceEnabled?: boolean; } export const DigitalDiceWrapper: FC = ({ isContextMenuEnabled = true, rollType, children, diceNotation, isDiceEnabled = true, action, rollKind, entityId, entityType, name, rollCallback, }) => { const [{ activeCampaign }] = useContext(GameLogContext); const [rollData, setRollData] = useState(); const mb = useAwaitMessageBroker(); const handleMessage = useCallback( (message: AnyMessage) => { if ( isMessage(message) && message.eventType === "dice/roll/fulfilled" && message.data.rollId === rollData?.rollId ) { rollCallback?.(rollData!); setRollData(undefined); } }, [rollCallback, rollData] ); // Only subscribe when there's a pending roll to listen for useEffect(() => { if (!mb || !rollCallback || !rollData) { return; } return mb.subscribe(handleMessage); }, [mb, rollCallback, rollData, handleMessage]); return ( {children} ); };