import React from "react"; import { connect } from "react-redux"; import { syncTransactionSelectors } from "@dndbeyond/character-rules-engine/es"; import { BuilderAppState } from "../../typings"; import { SyncBlockerLoadingPlaceholder } from "./SynchronousBlockerLoadingPlaceholder"; let showBlockerTimerId: number; let hideBlockerTimerId: number; interface Props { waitDelayToShow: number; waitDelayToHide: number; className: string; syncActive: boolean; } interface State { showBlocker: boolean; transitioning: boolean; } class SynchronousBlocker extends React.PureComponent { static defaultProps = { waitDelayToShow: 300, waitDelayToHide: 0, className: "", }; constructor(props) { super(props); this.state = { showBlocker: false, transitioning: false, }; } componentDidUpdate( prevProps: Readonly, prevState: Readonly, snapshot?: any ): void { const { syncActive, waitDelayToShow, waitDelayToHide } = this.props; if (syncActive === prevProps.syncActive) { return; } if (prevState.transitioning) { return; } if (syncActive) { window.clearTimeout(hideBlockerTimerId); this.setState({ transitioning: true, }); showBlockerTimerId = window.setTimeout(() => { this.setState({ showBlocker: true, transitioning: false, }); }, waitDelayToShow); } else { window.clearTimeout(showBlockerTimerId); if (waitDelayToHide) { this.setState({ transitioning: true, }); hideBlockerTimerId = window.setTimeout(() => { this.setState({ showBlocker: false, transitioning: false, }); }, waitDelayToHide); } else { this.setState({ showBlocker: false, }); } } } handleOverlayClick = (evt: React.MouseEvent): void => { evt.stopPropagation(); evt.nativeEvent.stopImmediatePropagation(); }; renderContent = (): React.ReactNode => { const { children } = this.props; if (children) { return children; } return ; }; render() { const { transitioning } = this.state; const { syncActive, className } = this.props; const classNames: Array = ["sync-blocker", className]; if (syncActive) { classNames.push("sync-blocker-active"); } else { classNames.push("sync-blocker-inactive"); } if (transitioning) { classNames.push("sync-blocker-transition-in-out"); } return (
{this.renderContent()}
); } } function mapStateToProps(state: BuilderAppState) { return { syncActive: syncTransactionSelectors.getActive(state), }; } export default connect(mapStateToProps)(SynchronousBlocker);