import React from 'react'; import { connect } from 'react-redux'; import BN from 'bn.js'; import { translateRaw } from 'translations'; import { NetworkConfig } from 'types/network'; import { Units } from 'libs/units'; import { AppState } from 'features/reducers'; import { getOffline, getNetworkConfig } from 'features/config'; import { transactionFieldsActions, transactionFieldsSelectors, transactionNetworkActions } from 'features/transaction'; import { ratesActions } from 'features/rates'; import AdvancedGas, { AdvancedOptions } from './components/AdvancedGas'; import SimpleGas from './components/SimpleGas'; import './TXMetaDataPanel.scss'; type SliderStates = 'simple' | 'advanced'; interface StateProps { gasPrice: AppState['transaction']['fields']['gasPrice']; offline: AppState['config']['meta']['offline']; network: NetworkConfig; } interface DispatchProps { inputGasPrice: transactionFieldsActions.TInputGasPrice; inputGasPriceIntent: transactionFieldsActions.TInputGasPriceIntent; fetchCCRates: ratesActions.TFetchCCRatesRequested; getNonceRequested: transactionNetworkActions.TGetNonceRequested; resetTransactionRequested: transactionFieldsActions.TResetTransactionRequested; } // Set default props for props that can't be truthy or falsy interface DefaultProps { initialState: SliderStates; } interface OwnProps { initialState?: SliderStates; disableToggle?: boolean; advancedGasOptions?: AdvancedOptions; className?: string; scheduling?: boolean; } type Props = DispatchProps & OwnProps & StateProps; interface State { gasPrice: AppState['transaction']['fields']['gasPrice']; sliderState: SliderStates; } class TXMetaDataPanel extends React.Component { public static defaultProps: DefaultProps = { initialState: 'simple' }; public state: State = { gasPrice: this.props.gasPrice, sliderState: (this.props as DefaultProps).initialState }; public componentWillMount() { if (!this.props.offline) { this.props.resetTransactionRequested(); } } public componentDidMount() { if (!this.props.offline) { this.props.fetchCCRates([this.props.network.unit]); this.props.getNonceRequested(); } } public UNSAFE_componentWillReceiveProps(nextProps: Props) { if ( (this.props.offline && !nextProps.offline) || this.props.network.unit !== nextProps.network.unit ) { this.props.fetchCCRates([this.props.network.unit]); } if (this.props.gasPrice !== nextProps.gasPrice) { this.setState({ gasPrice: nextProps.gasPrice }); } } public render() { const { offline, disableToggle, advancedGasOptions, className = '', scheduling } = this.props; const { gasPrice } = this.state; const showAdvanced = this.state.sliderState === 'advanced' || offline; return (

{showAdvanced ? ( ) : ( )} {!offline && !disableToggle && (
{showAdvanced ? `- ${translateRaw('TRANS_SIMPLE')}` : `+ ${translateRaw('TRANS_ADVANCED')}`}
)}
); } private toggleAdvanced = () => { this.setState({ sliderState: this.state.sliderState === 'advanced' ? 'simple' : 'advanced' }); }; private handleGasPriceInput = (raw: string) => { // Realistically, we're not going to end up with a > 32 bit int, so it's // safe to cast to float, multiply by gwei units, then big number, since // some of the inputs may be sub-one float values. const value = new BN(parseFloat(raw) * parseFloat(Units.gwei)); this.setState({ gasPrice: { raw, value } }); this.props.inputGasPriceIntent(raw); }; } function mapStateToProps(state: AppState): StateProps { return { gasPrice: transactionFieldsSelectors.getGasPrice(state), offline: getOffline(state), network: getNetworkConfig(state) }; } export default connect(mapStateToProps, { inputGasPrice: transactionFieldsActions.inputGasPrice, inputGasPriceIntent: transactionFieldsActions.inputGasPriceIntent, fetchCCRates: ratesActions.fetchCCRatesRequested, getNonceRequested: transactionNetworkActions.getNonceRequested, resetTransactionRequested: transactionFieldsActions.resetTransactionRequested })(TXMetaDataPanel);