/ common / components / ConfirmationModalTemplate / ConfirmationModalTemplate.tsx
ConfirmationModalTemplate.tsx
  1  import React from 'react';
  2  import { connect } from 'react-redux';
  3  
  4  import { translateRaw, translate } from 'translations';
  5  import { AppState } from 'features/reducers';
  6  import { getLanguageSelection } from 'features/config';
  7  import { transactionBroadcastActions, transactionSelectors } from 'features/transaction';
  8  import { walletSelectors } from 'features/wallet';
  9  import Modal, { IButton } from 'components/ui/Modal';
 10  import Spinner from 'components/ui/Spinner';
 11  import './ConfirmationModalTemplate.scss';
 12  
 13  interface DispatchProps {
 14    broadcastLocalTransactionRequested: transactionBroadcastActions.TBroadcastLocalTransactionRequested;
 15    broadcastWeb3TransactionRequested: transactionBroadcastActions.TBroadcastWeb3TransactionRequested;
 16  }
 17  
 18  interface StateProps {
 19    lang: string;
 20    walletTypes: walletSelectors.IWalletType;
 21    transactionBroadcasting: boolean;
 22  }
 23  
 24  export interface ConfirmButtonCBProps {
 25    type: IButton['type'];
 26    timeLocked: boolean;
 27    timeLeft: number;
 28    timePrefix: string;
 29    defaultText: string;
 30    onConfirm: ConfirmationModalTemplateClass['confirm'];
 31  }
 32  
 33  export interface OwnProps {
 34    isOpen?: boolean;
 35    Body: React.ReactElement<any>;
 36    withConfirmButton?(props: ConfirmButtonCBProps): IButton;
 37    onClose(): void;
 38  }
 39  
 40  interface State {
 41    timeToRead: number;
 42  }
 43  
 44  type Props = DispatchProps & StateProps & OwnProps;
 45  
 46  class ConfirmationModalTemplateClass extends React.Component<Props, State> {
 47    private readTimer = 0;
 48    public constructor(props: Props) {
 49      super(props);
 50      this.state = {
 51        timeToRead: 5
 52      };
 53    }
 54  
 55    // Count down 5 seconds before allowing them to confirm
 56    public componentDidMount() {
 57      this.readTimer = window.setInterval(() => {
 58        if (this.state.timeToRead > 0) {
 59          this.setState({ timeToRead: this.state.timeToRead - 1 });
 60        } else {
 61          window.clearInterval(this.readTimer);
 62        }
 63      }, 1000);
 64    }
 65  
 66    public render() {
 67      const { onClose, transactionBroadcasting, isOpen } = this.props;
 68      const { timeToRead } = this.state;
 69      const buttonPrefix = timeToRead > 0 ? `(${timeToRead}) ` : '';
 70      const defaultConfirmButton = {
 71        text: buttonPrefix + translateRaw('ACTION_11'),
 72        type: 'primary' as IButton['type'],
 73        disabled: timeToRead > 0,
 74        onClick: this.confirm
 75      };
 76  
 77      const confirmButton: IButton = this.props.withConfirmButton
 78        ? this.props.withConfirmButton({
 79            onConfirm: defaultConfirmButton.onClick,
 80            timeLeft: timeToRead,
 81            timePrefix: buttonPrefix,
 82            timeLocked: defaultConfirmButton.disabled,
 83            defaultText: translateRaw('ACTION_11'),
 84            type: defaultConfirmButton.type
 85          })
 86        : defaultConfirmButton;
 87  
 88      const buttons: IButton[] = [
 89        confirmButton,
 90        {
 91          text: translate('ACTION_2'),
 92          type: 'default',
 93          onClick: onClose
 94        }
 95      ];
 96  
 97      return (
 98        <Modal
 99          title={translateRaw('CONFIRM_TX_MODAL_TITLE')}
100          buttons={buttons}
101          handleClose={onClose}
102          disableButtons={transactionBroadcasting}
103          hideButtons={transactionBroadcasting}
104          isOpen={isOpen}
105        >
106          {transactionBroadcasting ? (
107            <React.Fragment>
108              <Spinner size="x5" />
109            </React.Fragment>
110          ) : (
111            <React.Fragment>{this.props.Body}</React.Fragment>
112          )}
113        </Modal>
114      );
115    }
116  
117    public componentWillUnmount() {
118      window.clearInterval(this.readTimer);
119    }
120  
121    private confirm = () => {
122      if (this.state.timeToRead < 1) {
123        this.props.walletTypes.isWeb3Wallet
124          ? this.props.broadcastWeb3TransactionRequested()
125          : this.props.broadcastLocalTransactionRequested();
126      }
127    };
128  }
129  
130  export const ConfirmationModalTemplate = connect(
131    (state: AppState) => ({
132      transactionBroadcasting: transactionSelectors.currentTransactionBroadcasting(state),
133      lang: getLanguageSelection(state),
134      walletTypes: walletSelectors.getWalletType(state)
135    }),
136    {
137      broadcastLocalTransactionRequested:
138        transactionBroadcastActions.broadcastLocalTransactionRequested,
139      broadcastWeb3TransactionRequested: transactionBroadcastActions.broadcastWeb3TransactionRequested
140    }
141  )(ConfirmationModalTemplateClass);