import clsx from "clsx"; import React, { FC } from "react"; import { connect, DispatchProp } from "react-redux"; import { useSearchParams } from "react-router-dom"; import { AnyAction } from "redux"; import { rulesEngineSelectors, characterActions, characterSelectors, CharacterStatusSlug, Constants, HitPointInfo, RuleData, CharacterTheme, CampaignDataContract, } from "@dndbeyond/character-rules-engine/es"; import ListTimeline from "@dndbeyond/fontawesome-cache/svgs/light/list-timeline.svg"; import { GameLogNotificationWrapper } from "@dndbeyond/game-log-components"; import { useSidebar } from "~/contexts/Sidebar"; import { PaneInfo } from "~/contexts/Sidebar/Sidebar"; import { PaneComponentEnum } from "~/subApps/sheet/components/Sidebar/types"; import { WatchTourDialog } from "~/subApps/sheet/components/WatchTourDialog"; import { GameLogState } from "~/tools/js/Shared/stores/typings"; import { appEnvSelectors } from "../../../Shared/selectors"; import StatusSummaryMobile from "../../components/StatusSummaryMobile"; import { SheetAppState } from "../../typings"; import CharacterHeaderInfo from "../CharacterHeaderInfo"; import styles from "./styles.module.css"; // TODO: We are typing with AnyAction here to work around issues with UnknownAction, the type that was introduced in Redux 5. // If we decide to modernize to Redux 5, we will need to refactor much of the Rules Engine redux usage. interface Props extends DispatchProp { hitPointInfo: HitPointInfo; fails: number; successes: number; deathCause: Constants.DeathCauseEnum; inspiration: boolean; ruleData: RuleData; isReadonly: boolean; status: CharacterStatusSlug | null; paneHistoryStart: PaneInfo["paneHistoryStart"]; gameLog?: GameLogState; theme: CharacterTheme; campaign: CampaignDataContract | null; } const CharacterHeaderMobile: FC = ({ paneHistoryStart, dispatch, hitPointInfo, fails, successes, deathCause, inspiration, ruleData, isReadonly, status, gameLog, theme, campaign, }) => { const [searchParams] = useSearchParams(); const isVttView = searchParams.get("view") === "vtt"; const handleHealthSummaryClick = (): void => { if (!isReadonly) { paneHistoryStart(PaneComponentEnum.HEALTH_MANAGE); } }; const handleInspirationClick = (): void => { dispatch(characterActions.inspirationSet(!inspiration)); }; const handleGameLogClick = (evt: React.MouseEvent): void => { evt.stopPropagation(); evt.nativeEvent.stopImmediatePropagation(); // Assuming dispatch is available in props or context paneHistoryStart(PaneComponentEnum.GAME_LOG); }; return (
{!isVttView && !isReadonly && (
)} {isReadonly && status === CharacterStatusSlug.PREMADE ? (
) : (
)}
); }; function mapStateToProps(state: SheetAppState) { return { hitPointInfo: rulesEngineSelectors.getHitPointInfo(state), fails: rulesEngineSelectors.getDeathSavesFailCount(state), successes: rulesEngineSelectors.getDeathSavesSuccessCount(state), inspiration: rulesEngineSelectors.getInspiration(state), ruleData: rulesEngineSelectors.getRuleData(state), deathCause: rulesEngineSelectors.getDeathCause(state), isReadonly: appEnvSelectors.getIsReadonly(state), status: characterSelectors.getStatusSlug(state), theme: rulesEngineSelectors.getCharacterTheme(state), gameLog: appEnvSelectors.getGameLog(state), campaign: rulesEngineSelectors.getCampaign(state), }; } const CharacterHeaderMobileContainer = (props) => { const { pane: { paneHistoryStart }, } = useSidebar(); return ( ); }; export default connect(mapStateToProps)(CharacterHeaderMobileContainer);