Daniel Kmak 985ea0fb89 Ethereum Alarm Clock Integration (#1343)
* [FEATURE] Initial EAC integration.

* Title and explanation

* [FEATURE] Move the Schedule Payment to the main tab.

* [FEATURE] TimeBounty slider.

* [FEATURE] Move to main menu.

* [FEATURE] Redirection to the DApp for details.

* [FEATURE] Timestamp scheduling

* Scheduling: Basic date and time widget

* Linting fixes

* Moved the datetime field to new tab

* Fixed push errors

* Added missing specs

* Undid unintentional UI change

* Fixed some failing tests

* Ignore datetime parameter when checking if a transaction is full

* Added a date selector widget and renamed ScheduleTimestamp to ScheduleDate

* Marked componentDidMount

* Initialized Pikaday

* Revert "Initialized Pikaday"

This reverts commit 4e5bf5b2b882f236f5977400abf9b7092cbd1592.

* Revert "Marked componentDidMount"

This reverts commit 85d52192ac58f4b6ca9219e702f7390cd27e582f.

* Revert "Added a date selector widget and renamed ScheduleTimestamp to ScheduleDate"

This reverts commit aaad0ac9b565a78d1bfc631754160919fd38a59b.

* Converted the date picker into a datetime picker

* Added decent styling to the datetimepicker

* Added validation to the datetime picker

* Fixed prepush errors for scheduling timestamp

* Adjusted validation logic scheduling timestamp

* [FEATURE] Move scheduling to main tab.

* [FEATURE] Timezone selector

* [FEATURE] Scheduling: Timezone selector

* Removed zombie files

* [FEATURE] Reimplement Time Bounty.

* [FEATURE] Time/block selector

* [FEATURE] Add Window Size field.

* [FEATURE] Time/block switch functionality

* Implemented time/block switcher fuctionality

* [FEATURE] Add Schedule Gas Price field.

* [FEATURE] Scheduling toggle

* [FEATURE] Add basic styling and network check.

* [FEATURE] Add Schedule Gas Limit field

* [FEATURE] "Scheduled" button styling

* Reordered, renamed and centered scheduling elements

* Added the toggle button styling

* Class -> ClassName

* [FEATURE] Add Deposit field

*  [FEATURE] Move scheduling code into one directory

* [FIX] Scheduling responsiveness

* [FIX] Datetime picker not working on md screens

* [FEATURE] Timestamp Scheduling basic functionality

* [FIX] Fix data serialization.

* [FEATURE] Timezone inclusion

* [FEATURE] Add ChronoLogic logo.

* [FEATURE] Add link to image.

* [FIX] Update CSS of logo.

* [FEATURE] Default Window Size

* [FEATURE] Modified Help component to enable acting as a tooltip

* [FEATURE] Call contract to validate scheduling params

* [FIX] Change moment import to fix tests

* [FEATURE] Gas estimation for scheduling

* [FEATURE] Additional validation

* [FEATURE] UI changes and descriptions

* [FEATURE] Add tooltip to window and fix fee display.

* [FIX] Fix ethereumjs-abi dependency.

* [FEATURE] Hide scheduling when sending tokens.

* [FIX] Improved styling datetime picker

* [FEATURE] Add Redux state for scheduling

* [FEATURE] Create Toggle component, Share code between components

* [FEATURE] Use Tooltip component for help.

* [FEATURE] Better datetime picker

* [FEATURE] Remove fee

* Trigger mycryptobuild

* [FIX] Timestamp scheduling - Validation match

* [FIX] EAC integration touchups

* [FIX] Code review fixes

* [FIX] Window Size type

* [FIX] Type fixes.

* [FIX] Make tooltips only show on icons + resposiveness fixes

* [FIX] Break tooltips into more lines

* [FIX] Remove unnecessary code.

* [FIX] Remove unnecessary code.

* [FIX] Remove unnecessary types declaration.

* [FIX] Fee class names
2018-04-14 17:21:33 -05:00

161 lines
4.5 KiB
TypeScript

import React from 'react';
import BN from 'bn.js';
import { connect } from 'react-redux';
import {
inputGasPrice,
TInputGasPrice,
inputGasPriceIntent,
TInputGasPriceIntent,
getNonceRequested,
TGetNonceRequested,
reset,
TReset,
ResetAction
} from 'actions/transaction';
import { fetchCCRatesRequested, TFetchCCRatesRequested } from 'actions/rates';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { AppState } from 'reducers';
import { Units } from 'libs/units';
import SimpleGas from './components/SimpleGas';
import AdvancedGas, { AdvancedOptions } from './components/AdvancedGas';
import './TXMetaDataPanel.scss';
import { getGasPrice } from 'selectors/transaction';
import { NetworkConfig } from 'types/network';
import { translateRaw } from 'translations';
type SliderStates = 'simple' | 'advanced';
interface StateProps {
gasPrice: AppState['transaction']['fields']['gasPrice'];
offline: AppState['config']['meta']['offline'];
network: NetworkConfig;
}
interface DispatchProps {
inputGasPrice: TInputGasPrice;
inputGasPriceIntent: TInputGasPriceIntent;
fetchCCRates: TFetchCCRatesRequested;
getNonceRequested: TGetNonceRequested;
reset: TReset;
}
// Set default props for props that can't be truthy or falsy
interface DefaultProps {
initialState: SliderStates;
}
interface OwnProps {
resetIncludeExcludeProperties?: ResetAction['payload'];
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<Props, State> {
public static defaultProps: DefaultProps = {
initialState: 'simple'
};
public state: State = {
gasPrice: this.props.gasPrice,
sliderState: (this.props as DefaultProps).initialState
};
public componentDidMount() {
if (!this.props.offline) {
this.props.reset(this.props.resetIncludeExcludeProperties);
this.props.fetchCCRates([this.props.network.unit]);
this.props.getNonceRequested();
}
}
public 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 (
<div className={`Gas col-md-12 ${className}`}>
<br />
{showAdvanced ? (
<AdvancedGas
gasPrice={gasPrice}
inputGasPrice={this.props.inputGasPrice}
options={advancedGasOptions}
scheduling={scheduling}
/>
) : (
<SimpleGas
gasPrice={gasPrice}
inputGasPrice={this.handleGasPriceInput}
setGasPrice={this.props.inputGasPrice}
/>
)}
{!offline &&
!disableToggle && (
<div className="help-block">
<a className="Gas-toggle" onClick={this.toggleAdvanced}>
{showAdvanced
? `- ${translateRaw('TRANS_SIMPLE')}`
: `+ ${translateRaw('TRANS_ADVANCED')}`}
</a>
</div>
)}
</div>
);
}
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: getGasPrice(state),
offline: getOffline(state),
network: getNetworkConfig(state)
};
}
export default connect(mapStateToProps, {
inputGasPrice,
inputGasPriceIntent,
fetchCCRates: fetchCCRatesRequested,
getNonceRequested,
reset
})(TXMetaDataPanel);