Skip to content

Commit

Permalink
[FEATURE] Smart Gas Price (#46)
Browse files Browse the repository at this point in the history
Ref: #44 DigixGlobal/governance-ui-components#381

Description
Added a Smart Gas Price component with Advanced options mode to be able to switch fast between the amount of gas price user would like to pay based on transaction times whose values are being fetched directly from ETHGasStation API.

Current behaviour just had a slider for gas price without any advanced options to quickly select it.

Test Plan
Before firing up the dev env, please make sure you also have the governance-ui-components PR is linked with this one during setup
Once you have dev setup up and running, open the app and login using Import JSON option
After logging in, click on Lock DGD button on the Header and enter the amount you'd like to lock
In the transaction details and signing screen, you should now see options to select the gas price similar to the design mentioned in the issue description
  • Loading branch information
eswarasai authored and mikej-digix committed Oct 8, 2019
1 parent 2f59743 commit 6f60946
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,15 @@

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { connect } from 'react-redux';

import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import Grid from '@material-ui/core/Grid';
import Collapse from '@material-ui/core/Collapse';
import Typography from '@material-ui/core/Typography';
import Card from '@material-ui/core/Card';
import TextField from '@material-ui/core/TextField';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import Slider from '@digix/mui/lib/components/SimpleSlider';

import '@digix/mui/lib/assets/css/simpleSlider.css';

import { withStyles } from '@material-ui/core/styles';
import { GasPrice } from '@digix/governance-ui-components/src/components/common';

import Button from '@material-ui/core/Button';
import LinearProgress from '@material-ui/core/LinearProgress';
Expand All @@ -36,109 +27,18 @@ const defaultState = {
autoBroadcast: true,
signedTx: null,
signingAction: undefined,
openAdvanced: false,
gasPrice: 20,
showAdvancedTab: true,
};

const styles = theme => ({
expand: {
transform: 'rotate(0deg)',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest
})
},
slider: {
margin: '3em 0 0 0'
},
advancedBtn: {
fontWeight: '300',
border: 0,
marginTop: '1.5em',
padding: 0,
fontSize: '0.8em',
textAlign: 'center'
},
expandOpen: {
transform: 'rotate(180deg)'
},
card: {
padding: '2rem',
borderRadius: '.5rem',
background: 'rgba(70, 78, 91, 0.2);',
boxShadow: 'none',
textAlign: 'center',
[theme.breakpoints.between('xs', 'sm')]: {
padding: '2em 1em'
}
},
noPadding: {
display: 'flex',
alignItems: 'center',
padding: '0 !important'
},
typography: {
margin: '1em 0 2em 0',
color: '#000'
},
voteSelection: {
background: '#E2CE98',
borderRadius: '50px',
textAlign: 'center',
padding: '0 !important'
},
selected: {
margin: '0',
// color: globalVars.tertiaryColor,
fontSize: '1.5em',
paddingRight: '1rem'
},
textField: {
// color: globalVars.tertiaryColor,
width: 'auto',
textAlign: 'center',
fontSize: '1.1em',
fontWeight: '600',
'&': {
'-moz-appearance': 'textfield'
},
'&::-webkit-inner-spin-button, &::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
margin: 0
}
},
noBorder: {
border: '0',
'&::before': {
borderBottom: '0'
},
':hover': {
border: 'none'
}
},
minValue: {
textAlign: 'left',
fontSize: '1.3em',
color: '#000',
marginTop: '1em'
},
maxValue: {
textAlign: 'right',
fontSize: '1.3em',
color: '#000',
marginTop: '1em'
}
});

class TransactionSigningOverlay extends Component {
static propTypes = {
data: PropTypes.object,
hideTxSigningModal: PropTypes.func.isRequired,
classes: PropTypes.object.isRequired
};

static defaultProps = {
data: undefined
data: undefined,
};

constructor(props) {
Expand All @@ -150,7 +50,7 @@ class TransactionSigningOverlay extends Component {
this.handleSign = this.handleSign.bind(this);
}

componentWillReceiveProps = nextProps => {
componentWillReceiveProps = (nextProps) => {
const { data } = nextProps;
if (data) {
const { txData } = data;
Expand All @@ -159,10 +59,10 @@ class TransactionSigningOverlay extends Component {
}
};

setGasPrice = gasPrice => {
setGasPrice = (gasPrice) => {
// this.props.setTxFee(gasPrice);
this.setState({
gasPrice
gasPrice,
});
};

Expand Down Expand Up @@ -206,110 +106,17 @@ class TransactionSigningOverlay extends Component {
this.props.hideTxSigningModal({ error: t.cancelled });
}

handleChange = (name, { min, max }) => event => {
handleChange = (name, { min, max }) => (event) => {
const value = parseFloat(event.target.value) || min;
this.setState({
[name]: value > max ? max : value
[name]: value > max ? max : value,
});
};

hideAdvancedTab = () => {
this.setState({ showAdvancedTab: false });
}

toggleAdvancedTab = (e) => {
e.preventDefault();
const { logTxn } = this.props.data;
const { openAdvanced } = this.state;

if (logTxn) {
logTxn.toggleAdvanced(!openAdvanced);
}

this.setState({ openAdvanced: !openAdvanced });
}

renderAdvancedTab() {
const t = this.props.data.translations.common;
const { classes } = this.props;
const { gasPrice, openAdvanced, showAdvancedTab } = this.state;

if (!showAdvancedTab) {
return null;
}

const MIN_GWEI = 1;
const MAX_GWEI = 100;
const range = {
min: MIN_GWEI,
max: MAX_GWEI,
};

const inputProps = {
step: 1,
...range,
className: classes.textField,
};

const classProps = {
classes: {
root: classes.textField,
input: classes.noBorder,
underline: classes.noBorder,
},
};

return (
<div>
<Button
className={classes.advancedBtn}
disableRipple
disableTouchRipple
onClick={this.toggleAdvancedTab}
variant="outlined"
>
{t.advanced}
<ExpandMoreIcon
className={classnames(classes.expand, {
[classes.expandOpen]: openAdvanced,
})}
/>
</Button>

<Collapse in={openAdvanced}>
<Card className={classes.card}>
<Grid container>
<Grid item xs={9} className={classes.noPadding}>
<Typography className={classes.typography}>{t.gasPrice}</Typography>
</Grid>
<Grid item xs={3} className={classes.voteSelection}>
<Typography className={classes.selected} variant="caption">
<TextField
inputProps={inputProps}
InputProps={classProps}
onChange={this.handleChange('gasPrice', range)}
value={gasPrice}
type="number"
/>
&nbsp;GWEI
</Typography>
</Grid>
<Grid item xs={12}>
<div className={classes.slider}>
<Slider onUpdate={this.setGasPrice} range={range} start={[gasPrice]} step={1} />
<Grid container>
<Grid item xs={6} className={classes.minValue}>{MIN_GWEI}</Grid>
<Grid item xs={6} className={classes.maxValue}>{MAX_GWEI}</Grid>
</Grid>
</div>
</Grid>
</Grid>
</Card>
</Collapse>
</div>
);
}

render() {
const { data } = this.props;
if (!data) {
Expand All @@ -325,7 +132,6 @@ class TransactionSigningOverlay extends Component {
signedTx,
signingAction,
loading,
gasPrice,
} = this.state;

if (!txData || !keystore) {
Expand All @@ -334,7 +140,7 @@ class TransactionSigningOverlay extends Component {

const { gasPrice: txGas, ...rest } = txData;
const newTxData = {
gasPrice: `0x${(Number(gasPrice) * 1e9).toString(16)}`,
gasPrice: `0x${(Number(this.state.gasPrice) * 1e9).toString(16)}`,
...rest,
};

Expand Down Expand Up @@ -379,7 +185,12 @@ class TransactionSigningOverlay extends Component {
translations={translations}
logTxn={logTxn}
/>
{this.renderAdvancedTab()}
{this.state.showAdvancedTab && (
<GasPrice
gas={newTxData.gas}
onGasPriceChange={this.setGasPrice}
/>
)}
</div>
) : (
<div>
Expand All @@ -392,7 +203,7 @@ class TransactionSigningOverlay extends Component {
content="Broadcast Transaction"
icon="bullhorn"
color="green"
onClick={e => {
onClick={(e) => {
e.preventDefault();
this.handleBroadcast({ signedTx });
}}
Expand All @@ -417,5 +228,5 @@ class TransactionSigningOverlay extends Component {

export default connect(
state => ({ data: getSigningModalData(state) }),
{ hideTxSigningModal }
)(withStyles(styles)(TransactionSigningOverlay));
{ hideTxSigningModal },
)(TransactionSigningOverlay);
Loading

0 comments on commit 6f60946

Please sign in to comment.