mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Final gas customization fixes
This commit is contained in:
parent
75d7545437
commit
d8e41a6aa5
@ -413,7 +413,7 @@ describe('Transaction Controller', function () {
|
||||
gasPrice: '0xa',
|
||||
}
|
||||
txController.txStateManager._saveTxList([
|
||||
{ id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [] },
|
||||
{ id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [{}] },
|
||||
])
|
||||
|
||||
expectedTxParams = Object.assign({}, txParams, { gasPrice: '0xb'})
|
||||
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import Loading from '../../../loading-screen'
|
||||
import GasPriceChart from '../../gas-price-chart'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
export default class AdvancedTabContent extends Component {
|
||||
static contextTypes = {
|
||||
@ -22,7 +23,21 @@ export default class AdvancedTabContent extends Component {
|
||||
insufficientBalance: PropTypes.bool,
|
||||
}
|
||||
|
||||
gasInput (value, onChange, min, insufficientBalance, precision, showGWEI) {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.debouncedGasLimitReset = debounce((dVal) => {
|
||||
if (dVal < 21000) {
|
||||
props.updateCustomGasLimit(21000)
|
||||
}
|
||||
}, 1000, { trailing: true })
|
||||
this.onChangeGasLimit = (val) => {
|
||||
props.updateCustomGasLimit(val)
|
||||
this.debouncedGasLimitReset(val)
|
||||
}
|
||||
}
|
||||
|
||||
gasInput (value, onChange, min, insufficientBalance, showGWEI) {
|
||||
return (
|
||||
<div className="advanced-tab__gas-edit-row__input-wrapper">
|
||||
<input
|
||||
@ -32,14 +47,13 @@ export default class AdvancedTabContent extends Component {
|
||||
type="number"
|
||||
value={value}
|
||||
min={min}
|
||||
precision={precision}
|
||||
onChange={event => onChange(Number(event.target.value))}
|
||||
/>
|
||||
<div className={classnames('advanced-tab__gas-edit-row__input-arrows', {
|
||||
'advanced-tab__gas-edit-row__input-arrows--error': insufficientBalance,
|
||||
})}>
|
||||
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap"><i className="fa fa-sm fa-angle-up" onClick={() => onChange(value + 1)} /></div>
|
||||
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap"><i className="fa fa-sm fa-angle-down" onClick={() => onChange(value - 1)} /></div>
|
||||
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap" onClick={() => onChange(value + 1)}><i className="fa fa-sm fa-angle-up" /></div>
|
||||
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap" onClick={() => onChange(value - 1)}><i className="fa fa-sm fa-angle-down" /></div>
|
||||
</div>
|
||||
{insufficientBalance && <div className="advanced-tab__gas-edit-row__insufficient-balance">
|
||||
Insufficient Balance
|
||||
@ -84,8 +98,8 @@ export default class AdvancedTabContent extends Component {
|
||||
renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit, insufficientBalance) {
|
||||
return (
|
||||
<div className="advanced-tab__gas-edit-rows">
|
||||
{ this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, 9, true) }
|
||||
{ this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, insufficientBalance, 0) }
|
||||
{ this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, true) }
|
||||
{ this.renderGasEditRow('gasLimit', customGasLimit, this.onChangeGasLimit, customGasLimit, insufficientBalance) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -148,6 +148,7 @@
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&__i-wrap:hover {
|
||||
|
@ -155,8 +155,11 @@ describe('AdvancedTabContent Component', function () {
|
||||
|
||||
describe('renderGasEditRows()', () => {
|
||||
let gasEditRows
|
||||
let tempOnChangeGasLimit
|
||||
|
||||
beforeEach(() => {
|
||||
tempOnChangeGasLimit = wrapper.instance().onChangeGasLimit
|
||||
wrapper.instance().onChangeGasLimit = () => 'mockOnChangeGasLimit'
|
||||
AdvancedTabContent.prototype.renderGasEditRow.resetHistory()
|
||||
gasEditRows = shallow(wrapper.instance().renderGasEditRows(
|
||||
'mockGasPrice',
|
||||
@ -167,6 +170,10 @@ describe('AdvancedTabContent Component', function () {
|
||||
))
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.instance().onChangeGasLimit = tempOnChangeGasLimit
|
||||
})
|
||||
|
||||
it('should render the gas-edit-rows root node', () => {
|
||||
assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows'))
|
||||
})
|
||||
@ -182,10 +189,10 @@ describe('AdvancedTabContent Component', function () {
|
||||
const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args
|
||||
assert.equal(renderGasEditRowSpyArgs.length, 2)
|
||||
assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [
|
||||
'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, 9, true,
|
||||
'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, true,
|
||||
].map(String))
|
||||
assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [
|
||||
'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', false, 0,
|
||||
'gasLimit', 'mockGasLimit', () => 'mockOnChangeGasLimit', 'mockGasLimit', false,
|
||||
].map(String))
|
||||
})
|
||||
})
|
||||
@ -234,7 +241,6 @@ describe('AdvancedTabContent Component', function () {
|
||||
const inputProps = gasInput.find('input').props()
|
||||
assert.equal(inputProps.min, 0)
|
||||
assert.equal(inputProps.value, 321)
|
||||
assert.equal(inputProps.precision, 8)
|
||||
})
|
||||
|
||||
it('should call the passed onChange method with the value of the input onChange event', () => {
|
||||
@ -257,9 +263,9 @@ describe('AdvancedTabContent Component', function () {
|
||||
8,
|
||||
false
|
||||
))
|
||||
const upArrow = gasInput.find('.fa-angle-up')
|
||||
const upArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(0)
|
||||
assert.equal(upArrow.props().onClick(), 329)
|
||||
const downArrow = gasInput.find('.fa-angle-down')
|
||||
const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1)
|
||||
assert.equal(downArrow.props().onClick(), 327)
|
||||
})
|
||||
})
|
||||
|
@ -89,7 +89,7 @@ export default class GasModalPageContainer extends Component {
|
||||
|
||||
renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) {
|
||||
return (
|
||||
<div>
|
||||
<div className="gas-modal-content__info-row-wrapper">
|
||||
<div className="gas-modal-content__info-row">
|
||||
<div className="gas-modal-content__info-row__send-info">
|
||||
<span className="gas-modal-content__info-row__send-info__label">{this.context.t('sendAmount')}</span>
|
||||
@ -167,7 +167,6 @@ export default class GasModalPageContainer extends Component {
|
||||
onClose={() => cancelAndClose()}
|
||||
onSubmit={() => {
|
||||
onSubmit(customModalGasLimitInHex, customModalGasPriceInHex)
|
||||
cancelAndClose()
|
||||
}}
|
||||
submitText={this.context.t('save')}
|
||||
headerCloseText={'Close'}
|
||||
|
@ -142,6 +142,7 @@ const mapDispatchToProps = dispatch => {
|
||||
dispatch(resetCustomData())
|
||||
dispatch(hideModal())
|
||||
},
|
||||
hideModal: () => dispatch(hideModal()),
|
||||
updateCustomGasPrice,
|
||||
convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)),
|
||||
convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))),
|
||||
@ -150,6 +151,8 @@ const mapDispatchToProps = dispatch => {
|
||||
dispatch(setGasPrice(newPrice))
|
||||
},
|
||||
updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
|
||||
updateCustomGasPrice(gasPrice)
|
||||
dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16))))
|
||||
return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
|
||||
},
|
||||
createSpeedUpTransaction: (txId, gasPrice) => {
|
||||
@ -172,6 +175,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||
updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate,
|
||||
createSpeedUpTransaction: dispatchCreateSpeedUpTransaction,
|
||||
hideSidebar: dispatchHideSidebar,
|
||||
cancelAndClose: dispatchCancelAndClose,
|
||||
hideModal: dispatchHideModal,
|
||||
...otherDispatchProps
|
||||
} = dispatchProps
|
||||
|
||||
@ -182,18 +187,27 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||
onSubmit: (gasLimit, gasPrice) => {
|
||||
if (isConfirm) {
|
||||
dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice)
|
||||
dispatchHideModal()
|
||||
} else if (isSpeedUp) {
|
||||
dispatchCreateSpeedUpTransaction(txId, gasPrice)
|
||||
dispatchHideSidebar()
|
||||
dispatchCancelAndClose()
|
||||
} else {
|
||||
dispatchSetGasData(gasLimit, gasPrice)
|
||||
dispatchHideGasButtonGroup()
|
||||
dispatchCancelAndClose()
|
||||
}
|
||||
},
|
||||
gasPriceButtonGroupProps: {
|
||||
...gasPriceButtonGroupProps,
|
||||
handleGasPriceSelection: dispatchUpdateCustomGasPrice,
|
||||
},
|
||||
cancelAndClose: () => {
|
||||
dispatchCancelAndClose()
|
||||
if (isSpeedUp) {
|
||||
dispatchHideSidebar()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,20 +255,29 @@ function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conver
|
||||
}
|
||||
|
||||
function getRenderableTimeEstimate (currentGasPrice, gasPrices, estimatedTimes) {
|
||||
const minGasPrice = gasPrices[0]
|
||||
const maxGasPrice = gasPrices[gasPrices.length - 1]
|
||||
let priceForEstimation = currentGasPrice
|
||||
if (currentGasPrice < minGasPrice) {
|
||||
priceForEstimation = minGasPrice
|
||||
} else if (currentGasPrice > maxGasPrice) {
|
||||
priceForEstimation = maxGasPrice
|
||||
}
|
||||
|
||||
const {
|
||||
closestLowerValueIndex,
|
||||
closestHigherValueIndex,
|
||||
closestHigherValue,
|
||||
closestLowerValue,
|
||||
} = getAdjacentGasPrices({ gasPrices, priceToPosition: currentGasPrice })
|
||||
} = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation })
|
||||
|
||||
const newTimeEstimate = extrapolateY({
|
||||
higherY: estimatedTimes[closestHigherValueIndex],
|
||||
lowerY: estimatedTimes[closestLowerValueIndex],
|
||||
higherX: closestHigherValue,
|
||||
lowerX: closestLowerValue,
|
||||
xForExtrapolation: currentGasPrice,
|
||||
xForExtrapolation: priceForEstimation,
|
||||
})
|
||||
|
||||
return formatTimeEstimate(newTimeEstimate)
|
||||
return formatTimeEstimate(newTimeEstimate, currentGasPrice > maxGasPrice, currentGasPrice < minGasPrice)
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&__subtitle {
|
||||
|
@ -82,10 +82,10 @@ describe('gas-modal-page-container container', () => {
|
||||
},
|
||||
gasEstimatesLoading: false,
|
||||
priceAndTimeEstimates: [
|
||||
{ gasprice: 3, expectedTime: '31' },
|
||||
{ gasprice: 4, expectedTime: '62' },
|
||||
{ gasprice: 5, expectedTime: '93' },
|
||||
{ gasprice: 6, expectedTime: '124' },
|
||||
{ gasprice: 3, expectedTime: 31 },
|
||||
{ gasprice: 4, expectedTime: 62 },
|
||||
{ gasprice: 5, expectedTime: 93 },
|
||||
{ gasprice: 6, expectedTime: 124 },
|
||||
],
|
||||
},
|
||||
confirmTransaction: {
|
||||
@ -235,7 +235,7 @@ describe('gas-modal-page-container container', () => {
|
||||
describe('updateConfirmTxGasAndCalculate()', () => {
|
||||
it('should dispatch a updateGasAndCalculate action with the correct props', () => {
|
||||
mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa')
|
||||
assert(dispatchSpy.calledOnce)
|
||||
assert.equal(dispatchSpy.callCount, 3)
|
||||
assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce)
|
||||
assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' })
|
||||
})
|
||||
@ -265,6 +265,8 @@ describe('gas-modal-page-container container', () => {
|
||||
someOtherDispatchProp: sinon.spy(),
|
||||
createSpeedUpTransaction: sinon.spy(),
|
||||
hideSidebar: sinon.spy(),
|
||||
hideModal: sinon.spy(),
|
||||
cancelAndClose: sinon.spy(),
|
||||
}
|
||||
ownProps = { someOwnProp: 123 }
|
||||
})
|
||||
@ -277,6 +279,7 @@ describe('gas-modal-page-container container', () => {
|
||||
dispatchProps.someOtherDispatchProp.resetHistory()
|
||||
dispatchProps.createSpeedUpTransaction.resetHistory()
|
||||
dispatchProps.hideSidebar.resetHistory()
|
||||
dispatchProps.hideModal.resetHistory()
|
||||
})
|
||||
it('should return the expected props when isConfirm is true', () => {
|
||||
const result = mergeProps(stateProps, dispatchProps, ownProps)
|
||||
@ -290,12 +293,14 @@ describe('gas-modal-page-container container', () => {
|
||||
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0)
|
||||
assert.equal(dispatchProps.setGasData.callCount, 0)
|
||||
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
|
||||
assert.equal(dispatchProps.hideModal.callCount, 0)
|
||||
|
||||
result.onSubmit()
|
||||
|
||||
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1)
|
||||
assert.equal(dispatchProps.setGasData.callCount, 0)
|
||||
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
|
||||
assert.equal(dispatchProps.hideModal.callCount, 1)
|
||||
|
||||
assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0)
|
||||
result.gasPriceButtonGroupProps.handleGasPriceSelection()
|
||||
@ -318,6 +323,7 @@ describe('gas-modal-page-container container', () => {
|
||||
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0)
|
||||
assert.equal(dispatchProps.setGasData.callCount, 0)
|
||||
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
|
||||
assert.equal(dispatchProps.cancelAndClose.callCount, 0)
|
||||
|
||||
result.onSubmit('mockNewLimit', 'mockNewPrice')
|
||||
|
||||
@ -325,6 +331,7 @@ describe('gas-modal-page-container container', () => {
|
||||
assert.equal(dispatchProps.setGasData.callCount, 1)
|
||||
assert.deepEqual(dispatchProps.setGasData.getCall(0).args, ['mockNewLimit', 'mockNewPrice'])
|
||||
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 1)
|
||||
assert.equal(dispatchProps.cancelAndClose.callCount, 1)
|
||||
|
||||
assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0)
|
||||
result.gasPriceButtonGroupProps.handleGasPriceSelection()
|
||||
@ -343,6 +350,7 @@ describe('gas-modal-page-container container', () => {
|
||||
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0)
|
||||
assert.equal(dispatchProps.setGasData.callCount, 0)
|
||||
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
|
||||
assert.equal(dispatchProps.cancelAndClose.callCount, 1)
|
||||
|
||||
assert.equal(dispatchProps.createSpeedUpTransaction.callCount, 1)
|
||||
assert.equal(dispatchProps.hideSidebar.callCount, 1)
|
||||
|
@ -137,7 +137,7 @@
|
||||
.gas-price-button-group--alt {
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
max-width: 342px;
|
||||
width: 95%;
|
||||
|
||||
&__button-fiat-price {
|
||||
font-size: 13px;
|
||||
|
@ -19,7 +19,7 @@ export default class GasPriceChart extends Component {
|
||||
gasPrices: PropTypes.array,
|
||||
estimatedTimes: PropTypes.array,
|
||||
gasPricesMax: PropTypes.number,
|
||||
estimatedTimesMax: PropTypes.string,
|
||||
estimatedTimesMax: PropTypes.number,
|
||||
currentPrice: PropTypes.number,
|
||||
updateCustomGasPrice: PropTypes.func,
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
import * as d3 from 'd3'
|
||||
import c3 from 'c3'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
const newBigSigDig = n => (new BigNumber(n.toPrecision(15)))
|
||||
const createOp = (a, b, op) => (newBigSigDig(a))[op](newBigSigDig(b))
|
||||
const bigNumMinus = (a = 0, b = 0) => createOp(a, b, 'minus')
|
||||
const bigNumDiv = (a = 0, b = 1) => createOp(a, b, 'div')
|
||||
|
||||
export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes, chart }) {
|
||||
const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({
|
||||
@ -24,7 +30,8 @@ export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices
|
||||
}
|
||||
|
||||
export function getCoordinateData (selector) {
|
||||
return d3.select(selector).node().getBoundingClientRect()
|
||||
const node = d3.select(selector).node()
|
||||
return node ? node.getBoundingClientRect() : {}
|
||||
}
|
||||
|
||||
export function generateDataUIObj (x, index, value) {
|
||||
@ -70,19 +77,22 @@ export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) {
|
||||
const slope = (higherY - lowerY) / (higherX - lowerX)
|
||||
const newTimeEstimate = -1 * (slope * (higherX - xForExtrapolation) - higherY)
|
||||
export function extrapolateY ({ higherY = 0, lowerY = 0, higherX = 0, lowerX = 0, xForExtrapolation = 0 }) {
|
||||
const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX))
|
||||
const newTimeEstimate = slope.times(bigNumMinus(higherX, xForExtrapolation)).minus(newBigSigDig(higherY)).negated()
|
||||
|
||||
return newTimeEstimate
|
||||
return newTimeEstimate.toNumber()
|
||||
}
|
||||
|
||||
|
||||
export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes }) {
|
||||
const chartMouseXPos = xMousePos - chartXStart
|
||||
const posPercentile = chartMouseXPos / chartWidth
|
||||
const chartMouseXPos = bigNumMinus(xMousePos, chartXStart)
|
||||
const posPercentile = bigNumDiv(chartMouseXPos, chartWidth)
|
||||
|
||||
const currentPosValue = (gasPrices[gasPrices.length - 1] - gasPrices[0]) * posPercentile + gasPrices[0]
|
||||
const currentPosValue = (bigNumMinus(gasPrices[gasPrices.length - 1], gasPrices[0]))
|
||||
.times(newBigSigDig(posPercentile))
|
||||
.plus(newBigSigDig(gasPrices[0]))
|
||||
.toNumber()
|
||||
|
||||
const {
|
||||
closestLowerValueIndex,
|
||||
@ -162,20 +172,28 @@ export function setSelectedCircle ({
|
||||
closestHigherValue,
|
||||
}) {
|
||||
const numberOfValues = chart.internal.data.xs.data1.length
|
||||
|
||||
const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`)
|
||||
let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`)
|
||||
let count = closestHigherValueIndex + 1
|
||||
|
||||
if (lowerX === higherX) {
|
||||
const { x: higherXAdjusted, y: higherYAdjusted } = getCoordinateData(`.c3-circle-${closestHigherValueIndex + 1}`)
|
||||
higherY = higherYAdjusted
|
||||
higherX = higherXAdjusted
|
||||
if (lowerX && higherX) {
|
||||
while (lowerX === higherX) {
|
||||
higherX = getCoordinateData(`.c3-circle-${count}`).x
|
||||
higherY = getCoordinateData(`.c3-circle-${count}`).y
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue)
|
||||
const currentX = bigNumMinus(higherX, lowerX)
|
||||
.times(bigNumMinus(newPrice, closestLowerValue))
|
||||
.div(bigNumMinus(closestHigherValue, closestLowerValue))
|
||||
.plus(newBigSigDig(lowerX))
|
||||
|
||||
const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX })
|
||||
|
||||
chart.internal.selectPoint(
|
||||
generateDataUIObj(currentX, numberOfValues, newTimeEstimate),
|
||||
generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate),
|
||||
numberOfValues
|
||||
)
|
||||
}
|
||||
@ -282,8 +300,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate
|
||||
.style('margin-top', flipTooltip ? '-16px' : '4px')
|
||||
|
||||
return {
|
||||
top: circleY - chartYStart - 19 + (flipTooltip ? circleWidth + 38 : 0),
|
||||
left: circleX - chartXStart + circleWidth - (gasPricesMaxPadded / 50),
|
||||
top: bigNumMinus(circleY, chartYStart).minus(19).plus(flipTooltip ? circleWidth + 38 : 0).toNumber(),
|
||||
left: bigNumMinus(circleX, chartXStart).plus(newBigSigDig(circleWidth)).minus(bigNumDiv(gasPricesMaxPadded, 50)).toNumber(),
|
||||
}
|
||||
},
|
||||
show: true,
|
||||
@ -298,8 +316,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate
|
||||
appendOrUpdateCircle.bind(this)({
|
||||
data,
|
||||
itemIndex,
|
||||
cx: () => data.x - chartXStart + 11,
|
||||
cy: () => data.value - chartYStart + 10,
|
||||
cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(),
|
||||
cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(),
|
||||
cssId: 'set-circle',
|
||||
appendOnly: true,
|
||||
})
|
||||
|
@ -399,7 +399,7 @@ function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
hideModal: (customOnHideOpts) => {
|
||||
dispatch(actions.hideModal())
|
||||
if (customOnHideOpts.action) {
|
||||
if (customOnHideOpts && customOnHideOpts.action) {
|
||||
dispatch(customOnHideOpts.action(...customOnHideOpts.args))
|
||||
}
|
||||
},
|
||||
|
@ -12,7 +12,7 @@ export default class PageContainerFooter extends Component {
|
||||
submitText: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
submitButtonType: PropTypes.string,
|
||||
hideCancel: PropTypes.func,
|
||||
hideCancel: PropTypes.bool,
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
|
@ -1,6 +1,11 @@
|
||||
.sidebar-left {
|
||||
display: flex;
|
||||
|
||||
.gas-modal-page-container {
|
||||
display: flex;
|
||||
|
||||
.page-container {
|
||||
flex: 1;
|
||||
max-width: 100%;
|
||||
|
||||
&__content {
|
||||
@ -12,6 +17,10 @@
|
||||
max-width: 344px;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
@media screen and (min-width: $break-small) {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gas-price-chart {
|
||||
@ -34,9 +43,10 @@
|
||||
}
|
||||
|
||||
.basic-tab-content {
|
||||
height: 318px;
|
||||
height: auto;
|
||||
margin-bottom: 0px;
|
||||
border-bottom: 1px solid #d2d8dd;
|
||||
flex: 1 1 70%;
|
||||
|
||||
@media screen and (max-width: $break-small) {
|
||||
padding-left: 14px;
|
||||
@ -55,6 +65,10 @@
|
||||
}
|
||||
|
||||
.advanced-tab {
|
||||
@media screen and (min-width: $break-small) {
|
||||
flex: 1 1 70%;
|
||||
}
|
||||
|
||||
&__fee-chart {
|
||||
height: 320px;
|
||||
|
||||
@ -72,8 +86,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.gas-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
.gas-modal-content__info-row {
|
||||
&__info-row-wrapper {
|
||||
display: flex;
|
||||
@media screen and (min-width: $break-small) {
|
||||
flex: 1 1 30%;
|
||||
}
|
||||
}
|
||||
|
||||
&__info-row {
|
||||
height: 170px;
|
||||
|
||||
@media screen and (max-width: $break-small) {
|
||||
@ -84,3 +109,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -220,18 +220,25 @@ export function fetchBasicGasAndTimeEstimates () {
|
||||
)
|
||||
.then(r => r.json())
|
||||
.then(({
|
||||
average,
|
||||
average: averageTimes10,
|
||||
avgWait,
|
||||
block_time: blockTime,
|
||||
blockNum,
|
||||
fast,
|
||||
fastest,
|
||||
fast: fastTimes10,
|
||||
fastest: fastestTimes10,
|
||||
fastestWait,
|
||||
fastWait,
|
||||
safeLow,
|
||||
safeLow: safeLowTimes10,
|
||||
safeLowWait,
|
||||
speed,
|
||||
}) => {
|
||||
const [average, fast, fastest, safeLow] = [
|
||||
averageTimes10,
|
||||
fastTimes10,
|
||||
fastestTimes10,
|
||||
safeLowTimes10,
|
||||
].map(price => (new BigNumber(price)).div(10).toNumber())
|
||||
|
||||
const basicEstimates = {
|
||||
average,
|
||||
avgWait,
|
||||
|
@ -32,15 +32,15 @@ describe('Gas Duck', () => {
|
||||
let tempFetch
|
||||
let tempDateNow
|
||||
const mockEthGasApiResponse = {
|
||||
average: 'mockAverage',
|
||||
average: 20,
|
||||
avgWait: 'mockAvgWait',
|
||||
block_time: 'mockBlock_time',
|
||||
blockNum: 'mockBlockNum',
|
||||
fast: 'mockFast',
|
||||
fastest: 'mockFastest',
|
||||
fast: 30,
|
||||
fastest: 40,
|
||||
fastestWait: 'mockFastestWait',
|
||||
fastWait: 'mockFastWait',
|
||||
safeLow: 'mockSafeLow',
|
||||
safeLow: 10,
|
||||
safeLowWait: 'mockSafeLowWait',
|
||||
speed: 'mockSpeed',
|
||||
}
|
||||
@ -338,15 +338,15 @@ describe('Gas Duck', () => {
|
||||
[{
|
||||
type: SET_BASIC_GAS_ESTIMATE_DATA,
|
||||
value: {
|
||||
average: 'mockAverage',
|
||||
average: 2,
|
||||
avgWait: 'mockAvgWait',
|
||||
blockTime: 'mockBlock_time',
|
||||
blockNum: 'mockBlockNum',
|
||||
fast: 'mockFast',
|
||||
fastest: 'mockFastest',
|
||||
fast: 3,
|
||||
fastest: 4,
|
||||
fastestWait: 'mockFastestWait',
|
||||
fastWait: 'mockFastWait',
|
||||
safeLow: 'mockSafeLow',
|
||||
safeLow: 1,
|
||||
safeLowWait: 'mockSafeLowWait',
|
||||
speed: 'mockSpeed',
|
||||
},
|
||||
|
@ -85,9 +85,9 @@ function getAveragePriceEstimateInHexWEI (state) {
|
||||
return getGasPriceInHexWei(averagePriceEstimate || '0x0')
|
||||
}
|
||||
|
||||
function getFastPriceEstimateInHexWEI (state, convertFromDecGWEI) {
|
||||
function getFastPriceEstimateInHexWEI (state) {
|
||||
const fastPriceEstimate = state.gas.basicEstimates.fast
|
||||
return getGasPriceInHexWei(fastPriceEstimate || '0x0', convertFromDecGWEI)
|
||||
return getGasPriceInHexWei(fastPriceEstimate || '0x0')
|
||||
}
|
||||
|
||||
function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) {
|
||||
@ -100,15 +100,6 @@ function getBasicGasEstimateBlockTime (state) {
|
||||
return state.gas.basicEstimates.blockTime
|
||||
}
|
||||
|
||||
function apiEstimateModifiedToGWEI (estimate) {
|
||||
return multiplyCurrencies(estimate, 0.10, {
|
||||
toNumericBase: 'hex',
|
||||
multiplicandBase: 10,
|
||||
multiplierBase: 10,
|
||||
numberOfDecimals: 9,
|
||||
})
|
||||
}
|
||||
|
||||
function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) {
|
||||
return conversionUtil(calcGasTotal(gasLimit, estimate), {
|
||||
fromNumericBase: 'hex',
|
||||
@ -118,26 +109,18 @@ function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9)
|
||||
})
|
||||
}
|
||||
|
||||
function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9, convertFromDecGWEI) {
|
||||
const initialConversion = convertFromDecGWEI
|
||||
? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' })
|
||||
: apiEstimateModifiedToGWEI
|
||||
|
||||
function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) {
|
||||
return pipe(
|
||||
initialConversion,
|
||||
x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }),
|
||||
partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]),
|
||||
formatETHFee
|
||||
)(estimate, gasLimit)
|
||||
}
|
||||
|
||||
|
||||
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate, convertFromDecGWEI) {
|
||||
const initialConversion = convertFromDecGWEI
|
||||
? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' })
|
||||
: apiEstimateModifiedToGWEI
|
||||
|
||||
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) {
|
||||
return pipe(
|
||||
initialConversion,
|
||||
x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }),
|
||||
partialRight(basicPriceEstimateToETHTotal, [gasLimit]),
|
||||
partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]),
|
||||
partialRight(formatCurrency, [convertedCurrency])
|
||||
@ -153,14 +136,26 @@ function getTimeEstimateInSeconds (blockWaitEstimate) {
|
||||
})
|
||||
}
|
||||
|
||||
function formatTimeEstimate (totalSeconds) {
|
||||
function formatTimeEstimate (totalSeconds, greaterThanMax, lessThanMin) {
|
||||
const minutes = Math.floor(totalSeconds / 60)
|
||||
const seconds = Math.floor(totalSeconds % 60)
|
||||
|
||||
if (!minutes && !seconds) {
|
||||
return '...'
|
||||
}
|
||||
|
||||
let symbol = '~'
|
||||
if (greaterThanMax) {
|
||||
symbol = '< '
|
||||
} else if (lessThanMin) {
|
||||
symbol = '> '
|
||||
}
|
||||
|
||||
const formattedMin = `${minutes ? minutes + ' min' : ''}`
|
||||
const formattedSec = `${seconds ? seconds + ' sec' : ''}`
|
||||
const formattedCombined = formattedMin && formattedSec
|
||||
? `~${formattedMin} ${formattedSec}`
|
||||
: '~' + [formattedMin, formattedSec].find(t => t)
|
||||
? `${symbol}${formattedMin} ${formattedSec}`
|
||||
: symbol + [formattedMin, formattedSec].find(t => t)
|
||||
|
||||
return formattedCombined
|
||||
}
|
||||
@ -182,13 +177,9 @@ function priceEstimateToWei (priceEstimate) {
|
||||
})
|
||||
}
|
||||
|
||||
function getGasPriceInHexWei (price, convertFromDecGWEI) {
|
||||
const initialConversion = convertFromDecGWEI
|
||||
? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' })
|
||||
: apiEstimateModifiedToGWEI
|
||||
|
||||
function getGasPriceInHexWei (price) {
|
||||
return pipe(
|
||||
initialConversion,
|
||||
x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }),
|
||||
priceEstimateToWei,
|
||||
addHexPrefix
|
||||
)(price)
|
||||
@ -259,19 +250,19 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) {
|
||||
return [
|
||||
{
|
||||
labelKey: 'fastest',
|
||||
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate, true),
|
||||
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate),
|
||||
feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
|
||||
priceInHexWei: getGasPriceInHexWei(fastest, true),
|
||||
},
|
||||
{
|
||||
labelKey: 'fast',
|
||||
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate, true),
|
||||
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate),
|
||||
feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
|
||||
priceInHexWei: getGasPriceInHexWei(fast, true),
|
||||
},
|
||||
{
|
||||
labelKey: 'slow',
|
||||
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate, true),
|
||||
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate),
|
||||
feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
|
||||
priceInHexWei: getGasPriceInHexWei(safeLow, true),
|
||||
},
|
||||
|
@ -109,11 +109,11 @@ describe('custom-gas selectors', () => {
|
||||
gas: {
|
||||
basicEstimates: {
|
||||
blockTime: 14.16326530612245,
|
||||
safeLow: 25,
|
||||
safeLow: 2.5,
|
||||
safeLowWait: 6.6,
|
||||
fast: 50,
|
||||
fast: 5,
|
||||
fastWait: 3.3,
|
||||
fastest: 100,
|
||||
fastest: 10,
|
||||
fastestWait: 0.5,
|
||||
},
|
||||
},
|
||||
@ -154,11 +154,11 @@ describe('custom-gas selectors', () => {
|
||||
gas: {
|
||||
basicEstimates: {
|
||||
blockTime: 14.16326530612245,
|
||||
safeLow: 50,
|
||||
safeLow: 5,
|
||||
safeLowWait: 13.2,
|
||||
fast: 100,
|
||||
fast: 10,
|
||||
fastWait: 6.6,
|
||||
fastest: 200,
|
||||
fastest: 20,
|
||||
fastestWait: 1.0,
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user