From 77258f8636de2bfd884fee36ff519d0227712a27 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Tue, 28 Aug 2018 11:16:24 -0400 Subject: [PATCH] add gas station component --- embark-ui/src/api/index.js | 1 - embark-ui/src/components/ContractFunctions.js | 14 +- embark-ui/src/components/GasStation.js | 142 ++++++++++++++++++ .../containers/ContractDeploymentContainer.js | 35 +++-- embark-ui/src/reducers/selectors.js | 4 + 5 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 embark-ui/src/components/GasStation.js diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js index 350a7cd80..87ad2ad55 100644 --- a/embark-ui/src/api/index.js +++ b/embark-ui/src/api/index.js @@ -2,7 +2,6 @@ import axios from "axios"; import constants from '../constants'; function get(path, params, endpoint) { - console.log('GET ', (endpoint || constants.httpEndpoint) + path); return axios.get((endpoint || constants.httpEndpoint) + path, params) .then((response) => { return {response, error: null}; diff --git a/embark-ui/src/components/ContractFunctions.js b/embark-ui/src/components/ContractFunctions.js index e52289f31..473836893 100644 --- a/embark-ui/src/components/ContractFunctions.js +++ b/embark-ui/src/components/ContractFunctions.js @@ -12,11 +12,11 @@ import { class ContractFunction extends Component { constructor(props) { super(props); - this.state = { inputs: {} }; + this.state = {inputs: {}}; } buttonTitle() { - const { method } =this.props; + const {method} = this.props; if (method.name === 'constructor') { return 'Deploy'; } @@ -24,7 +24,7 @@ class ContractFunction extends Component { return (method.mutability === 'view' || method.mutability === 'pure') ? 'Call' : 'Send'; } - inputsAsArray(){ + inputsAsArray() { return this.props.method.inputs .map(input => this.state.inputs[input.name]) .filter(value => value); @@ -33,7 +33,7 @@ class ContractFunction extends Component { handleChange(e, name) { let newInputs = this.state.inputs; newInputs[name] = e.target.value; - this.setState({ inputs: newInputs}); + this.setState({inputs: newInputs}); } handleCall(e) { @@ -63,7 +63,7 @@ class ContractFunction extends Component { {this.buttonTitle()} - + {this.props.contractFunctions && this.props.contractFunctions.length > 0 && {this.props.contractFunctions.map(contractFunction => ( @@ -72,7 +72,7 @@ class ContractFunction extends Component { ))} - + } @@ -106,7 +106,7 @@ const ContractFunctions = (props) => { method={method} contractFunctions={filterContractFunctions(props.contractFunctions, contractProfile.name, method.name)} contractProfile={contractProfile} - postContractFunction={props.postContractFunction} />)} + postContractFunction={props.postContractFunction}/>)} ); }; diff --git a/embark-ui/src/components/GasStation.js b/embark-ui/src/components/GasStation.js new file mode 100644 index 000000000..150dcf972 --- /dev/null +++ b/embark-ui/src/components/GasStation.js @@ -0,0 +1,142 @@ +import PropTypes from "prop-types"; +import React, {Component} from 'react'; +import {Card, Form, Grid, StampCard} from 'tabler-react'; + +const test = { + "fast": 50.0, + "speed": 0.998437456605574, + "fastest": 400.0, + "avgWait": 1.9, + "fastWait": 0.7, + "blockNum": 6228803, + "safeLowWait": 1.9, + "block_time": 14.326530612244898, + "fastestWait": 0.5, + "safeLow": 24.0, + "average": 24.0 +}; +const COLORS = { + good: 'green', + medium: 'yellow', + bad: 'red' +}; + +class GasStation extends Component { + constructor(props) { + super(props); + if (!props.gasStats) { + return console.error('gasStats is a needed Prop for GasStation'); + } + + this.state = {gasSliderIndex: 0}; + this.formattedGasStats = GasStation.formatGasStats(props.gasStats); + } + + static formatGasStats(gasStats) { + const { + fast, speed, fastest, avgWait, fastWait, blockNum, safeLowWait, + block_time, fastestWait, safeLow, average + } = gasStats; + return { + average: {price: average, wait: avgWait}, + blockTime: block_time, + blockNum, + speed, + gasSteps: [ + {price: safeLow, wait: safeLowWait}, + {price: fast, wait: fastWait}, + {price: fastest, wait: fastestWait} + ] + }; + } + + gasSliderChange(e) { + this.setState({ + gasSliderIndex: e.target.value + }); + } + + static getColorForWait(wait) { + if (wait <= 1) { + return COLORS.good; + } + if (wait <= 3) { + return COLORS.medium; + } + return COLORS.bad; + } + + static getColorForPrice(gasPrice) { + if (gasPrice <= 20) { + return COLORS.good; + } + if (gasPrice <= 40) { + return COLORS.medium; + } + return COLORS.bad; + } + + render() { + const currentGasStep = this.formattedGasStats.gasSteps[this.state.gasSliderIndex]; + return + + + + Gas Price Estimator + + + + + + + {currentGasStep.price / 10} GWei + + + + + {currentGasStep.wait} minutes + + + + + + this.gasSliderChange(e)} + /> + + + + + + + Average Price: {this.formattedGasStats.average.price / 10} Gwei + + + + + Average Wait: {this.formattedGasStats.average.wait} min + + + + + Last Block: {this.formattedGasStats.blockNum} + + + + + + + ; + } +} + +GasStation.propTypes = { + gasStats: PropTypes.object.isRequired +}; + +export default GasStation; diff --git a/embark-ui/src/containers/ContractDeploymentContainer.js b/embark-ui/src/containers/ContractDeploymentContainer.js index 556b158ce..0af3e19e6 100644 --- a/embark-ui/src/containers/ContractDeploymentContainer.js +++ b/embark-ui/src/containers/ContractDeploymentContainer.js @@ -3,10 +3,15 @@ import {connect} from 'react-redux'; import PropTypes from 'prop-types'; import {withRouter} from 'react-router-dom'; -import {contractProfile as contractProfileAction, contractDeploy as contractDeployAction, ethGas as ethGasAction} from '../actions'; +import { + contractProfile as contractProfileAction, + contractDeploy as contractDeployAction, + ethGas as ethGasAction +} from '../actions'; import ContractFunctions from '../components/ContractFunctions'; import DataWrapper from "../components/DataWrapper"; -import {getContractProfile, getContractDeploys} from "../reducers/selectors"; +import GasStation from "../components/GasStation"; +import {getContractProfile, getContractDeploys, getGasStats} from "../reducers/selectors"; class ContractDeploymentContainer extends Component { componentDidMount() { @@ -16,14 +21,23 @@ class ContractDeploymentContainer extends Component { render() { return ( - ( - - )} /> + + ( + + )}/> + + ( + + )}/> + + ); } } @@ -32,6 +46,7 @@ function mapStateToProps(state, props) { return { contractProfile: getContractProfile(state, props.match.params.contractName), contractDeploys: getContractDeploys(state, props.match.params.contractName), + gasStats: getGasStats(state), error: state.errorMessage, loading: state.loading }; diff --git a/embark-ui/src/reducers/selectors.js b/embark-ui/src/reducers/selectors.js index 7f3474a35..8edea1edf 100644 --- a/embark-ui/src/reducers/selectors.js +++ b/embark-ui/src/reducers/selectors.js @@ -84,6 +84,10 @@ export function getVersions(state) { return state.entities.versions; } +export function getGasStats(state) { + return state.entities.gasStats[state.entities.gasStats.length - 1]; +} + export function isWeb3Enabled(state) { return Boolean(state.entities.versions.find((version) => version.name === 'web3')); }