mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add loading spinners when waiting for APIs in the gas customization modal
This commit is contained in:
parent
7f2c5c09de
commit
7ffea926f2
@ -1,6 +1,7 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
import Loading from '../../../loading-screen'
|
||||||
import GasPriceChart from '../../gas-price-chart'
|
import GasPriceChart from '../../gas-price-chart'
|
||||||
|
|
||||||
export default class AdvancedTabContent extends Component {
|
export default class AdvancedTabContent extends Component {
|
||||||
@ -13,6 +14,7 @@ export default class AdvancedTabContent extends Component {
|
|||||||
updateCustomGasLimit: PropTypes.func,
|
updateCustomGasLimit: PropTypes.func,
|
||||||
customGasPrice: PropTypes.number,
|
customGasPrice: PropTypes.number,
|
||||||
customGasLimit: PropTypes.number,
|
customGasLimit: PropTypes.number,
|
||||||
|
gasEstimatesLoading: PropTypes.bool,
|
||||||
millisecondsRemaining: PropTypes.number,
|
millisecondsRemaining: PropTypes.number,
|
||||||
totalFee: PropTypes.string,
|
totalFee: PropTypes.string,
|
||||||
timeRemaining: PropTypes.string,
|
timeRemaining: PropTypes.string,
|
||||||
@ -98,6 +100,7 @@ export default class AdvancedTabContent extends Component {
|
|||||||
insufficientBalance,
|
insufficientBalance,
|
||||||
totalFee,
|
totalFee,
|
||||||
gasChartProps,
|
gasChartProps,
|
||||||
|
gasEstimatesLoading,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -112,7 +115,10 @@ export default class AdvancedTabContent extends Component {
|
|||||||
insufficientBalance
|
insufficientBalance
|
||||||
) }
|
) }
|
||||||
<div className="advanced-tab__fee-chart__title">Live Gas Price Predictions</div>
|
<div className="advanced-tab__fee-chart__title">Live Gas Price Predictions</div>
|
||||||
<GasPriceChart {...gasChartProps} updateCustomGasPrice={updateCustomGasPrice} />
|
{!gasEstimatesLoading
|
||||||
|
? <GasPriceChart {...gasChartProps} updateCustomGasPrice={updateCustomGasPrice} />
|
||||||
|
: <Loading />
|
||||||
|
}
|
||||||
<div className="advanced-tab__fee-chart__speed-buttons">
|
<div className="advanced-tab__fee-chart__speed-buttons">
|
||||||
<span>Slower</span>
|
<span>Slower</span>
|
||||||
<span>Faster</span>
|
<span>Faster</span>
|
||||||
|
@ -5,6 +5,7 @@ import sinon from 'sinon'
|
|||||||
import AdvancedTabContent from '../advanced-tab-content.component.js'
|
import AdvancedTabContent from '../advanced-tab-content.component.js'
|
||||||
|
|
||||||
import GasPriceChart from '../../../gas-price-chart'
|
import GasPriceChart from '../../../gas-price-chart'
|
||||||
|
import Loading from '../../../../loading-screen'
|
||||||
|
|
||||||
const propsMethodSpies = {
|
const propsMethodSpies = {
|
||||||
updateCustomGasPrice: sinon.spy(),
|
updateCustomGasPrice: sinon.spy(),
|
||||||
@ -60,6 +61,22 @@ describe('AdvancedTabContent Component', function () {
|
|||||||
assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons'))
|
assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should render a loading component instead of the chart if gasEstimatesLoading is true', () => {
|
||||||
|
wrapper.setProps({ gasEstimatesLoading: true })
|
||||||
|
const advancedTabChildren = wrapper.children()
|
||||||
|
assert.equal(advancedTabChildren.length, 2)
|
||||||
|
|
||||||
|
assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary'))
|
||||||
|
assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart'))
|
||||||
|
|
||||||
|
const feeChartDiv = advancedTabChildren.at(1)
|
||||||
|
|
||||||
|
assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows'))
|
||||||
|
assert(feeChartDiv.childAt(1).hasClass('advanced-tab__fee-chart__title'))
|
||||||
|
assert(feeChartDiv.childAt(2).is(Loading))
|
||||||
|
assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons'))
|
||||||
|
})
|
||||||
|
|
||||||
it('should call renderDataSummary with the expected params', () => {
|
it('should call renderDataSummary with the expected params', () => {
|
||||||
assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1)
|
assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1)
|
||||||
const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args
|
const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import Loading from '../../../loading-screen'
|
||||||
import GasPriceButtonGroup from '../../gas-price-button-group'
|
import GasPriceButtonGroup from '../../gas-price-button-group'
|
||||||
|
|
||||||
export default class BasicTabContent extends Component {
|
export default class BasicTabContent extends Component {
|
||||||
@ -12,15 +13,20 @@ export default class BasicTabContent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { gasPriceButtonGroupProps } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="basic-tab-content">
|
<div className="basic-tab-content">
|
||||||
<div className="basic-tab-content__title">Estimated Processing Times</div>
|
<div className="basic-tab-content__title">Estimated Processing Times</div>
|
||||||
<div className="basic-tab-content__blurb">Select a higher gas fee to accelerate the processing of your transaction.*</div>
|
<div className="basic-tab-content__blurb">Select a higher gas fee to accelerate the processing of your transaction.*</div>
|
||||||
<GasPriceButtonGroup
|
{!gasPriceButtonGroupProps.loading
|
||||||
|
? <GasPriceButtonGroup
|
||||||
className="gas-price-button-group--alt"
|
className="gas-price-button-group--alt"
|
||||||
showCheck={true}
|
showCheck={true}
|
||||||
{...this.props.gasPriceButtonGroupProps}
|
{...gasPriceButtonGroupProps}
|
||||||
/>
|
/>
|
||||||
|
: <Loading />
|
||||||
|
}
|
||||||
<div className="basic-tab-content__footer-blurb">* Accelerating a transaction by using a higher gas price increases its chances of getting processed by the network faster, but it is not always guaranteed.</div>
|
<div className="basic-tab-content__footer-blurb">* Accelerating a transaction by using a higher gas price increases its chances of getting processed by the network faster, but it is not always guaranteed.</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,7 @@ import { shallow } from 'enzyme'
|
|||||||
import BasicTabContent from '../basic-tab-content.component'
|
import BasicTabContent from '../basic-tab-content.component'
|
||||||
|
|
||||||
import GasPriceButtonGroup from '../../../gas-price-button-group/'
|
import GasPriceButtonGroup from '../../../gas-price-button-group/'
|
||||||
|
import Loading from '../../../../loading-screen'
|
||||||
|
|
||||||
const mockGasPriceButtonGroupProps = {
|
const mockGasPriceButtonGroupProps = {
|
||||||
buttonDataLoading: false,
|
buttonDataLoading: false,
|
||||||
@ -60,6 +61,7 @@ describe('BasicTabContent Component', function () {
|
|||||||
noButtonActiveByDefault,
|
noButtonActiveByDefault,
|
||||||
showCheck,
|
showCheck,
|
||||||
} = wrapper.find(GasPriceButtonGroup).props()
|
} = wrapper.find(GasPriceButtonGroup).props()
|
||||||
|
assert.equal(wrapper.find(GasPriceButtonGroup).length, 1)
|
||||||
assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading)
|
assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading)
|
||||||
assert.equal(className, mockGasPriceButtonGroupProps.className)
|
assert.equal(className, mockGasPriceButtonGroupProps.className)
|
||||||
assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault)
|
assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault)
|
||||||
@ -67,5 +69,14 @@ describe('BasicTabContent Component', function () {
|
|||||||
assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo)
|
assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo)
|
||||||
assert.equal(JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection))
|
assert.equal(JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should render a loading component instead of the GasPriceButtonGroup if gasPriceButtonGroupProps.loading is true', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
gasPriceButtonGroupProps: { ...mockGasPriceButtonGroupProps, loading: true },
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.equal(wrapper.find(GasPriceButtonGroup).length, 0)
|
||||||
|
assert.equal(wrapper.find(Loading).length, 1)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -68,6 +68,7 @@ export default class GasModalPageContainer extends Component {
|
|||||||
gasChartProps,
|
gasChartProps,
|
||||||
currentTimeEstimate,
|
currentTimeEstimate,
|
||||||
insufficientBalance,
|
insufficientBalance,
|
||||||
|
gasEstimatesLoading,
|
||||||
}) {
|
}) {
|
||||||
const { transactionFee } = this.props
|
const { transactionFee } = this.props
|
||||||
return (
|
return (
|
||||||
@ -81,6 +82,7 @@ export default class GasModalPageContainer extends Component {
|
|||||||
totalFee={newTotalFiat}
|
totalFee={newTotalFiat}
|
||||||
gasChartProps={gasChartProps}
|
gasChartProps={gasChartProps}
|
||||||
insufficientBalance={insufficientBalance}
|
insufficientBalance={insufficientBalance}
|
||||||
|
gasEstimatesLoading={gasEstimatesLoading}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import {
|
|||||||
formatTimeEstimate,
|
formatTimeEstimate,
|
||||||
getFastPriceEstimateInHexWEI,
|
getFastPriceEstimateInHexWEI,
|
||||||
getBasicGasEstimateLoadingStatus,
|
getBasicGasEstimateLoadingStatus,
|
||||||
|
getGasEstimatesLoadingStatus,
|
||||||
getCustomGasLimit,
|
getCustomGasLimit,
|
||||||
getCustomGasPrice,
|
getCustomGasPrice,
|
||||||
getDefaultActiveButtonIndex,
|
getDefaultActiveButtonIndex,
|
||||||
@ -65,6 +66,8 @@ import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price
|
|||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
const { transaction = {} } = ownProps
|
const { transaction = {} } = ownProps
|
||||||
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state)
|
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state)
|
||||||
|
const gasEstimatesLoading = getGasEstimatesLoadingStatus(state)
|
||||||
|
|
||||||
const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id)
|
const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id)
|
||||||
const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice
|
const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice
|
||||||
const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit
|
const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit
|
||||||
@ -127,6 +130,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
isSpeedUp: transaction.status === 'submitted',
|
isSpeedUp: transaction.status === 'submitted',
|
||||||
txId: transaction.id,
|
txId: transaction.id,
|
||||||
insufficientBalance,
|
insufficientBalance,
|
||||||
|
gasEstimatesLoading,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +232,7 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
customGasLimit: 456,
|
customGasLimit: 456,
|
||||||
newTotalFiat: '$0.30',
|
newTotalFiat: '$0.30',
|
||||||
currentTimeEstimate: '1 min 31 sec',
|
currentTimeEstimate: '1 min 31 sec',
|
||||||
|
gasEstimatesLoading: 'mockGasEstimatesLoading',
|
||||||
})
|
})
|
||||||
const advancedTabContentProps = renderAdvancedTabContentResult.props
|
const advancedTabContentProps = renderAdvancedTabContentResult.props
|
||||||
assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice')
|
assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice')
|
||||||
@ -240,6 +241,7 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
assert.equal(advancedTabContentProps.customGasLimit, 456)
|
assert.equal(advancedTabContentProps.customGasLimit, 456)
|
||||||
assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec')
|
assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec')
|
||||||
assert.equal(advancedTabContentProps.totalFee, '$0.30')
|
assert.equal(advancedTabContentProps.totalFee, '$0.30')
|
||||||
|
assert.equal(advancedTabContentProps.gasEstimatesLoading, 'mockGasEstimatesLoading')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ describe('gas-modal-page-container container', () => {
|
|||||||
limit: 'aaaaaaaa',
|
limit: 'aaaaaaaa',
|
||||||
price: 'ffffffff',
|
price: 'ffffffff',
|
||||||
},
|
},
|
||||||
|
gasEstimatesLoading: false,
|
||||||
priceAndTimeEstimates: [
|
priceAndTimeEstimates: [
|
||||||
{ gasprice: 3, expectedTime: '31' },
|
{ gasprice: 3, expectedTime: '31' },
|
||||||
{ gasprice: 4, expectedTime: '62' },
|
{ gasprice: 4, expectedTime: '62' },
|
||||||
@ -118,6 +119,7 @@ describe('gas-modal-page-container container', () => {
|
|||||||
defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff',
|
defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff',
|
||||||
gasButtonInfo: 'mockRenderableBasicEstimateData:4',
|
gasButtonInfo: 'mockRenderableBasicEstimateData:4',
|
||||||
},
|
},
|
||||||
|
gasEstimatesLoading: false,
|
||||||
hideBasic: true,
|
hideBasic: true,
|
||||||
infoRowProps: {
|
infoRowProps: {
|
||||||
originalTotalFiat: '637.41',
|
originalTotalFiat: '637.41',
|
||||||
|
@ -33,6 +33,7 @@ const selectors = {
|
|||||||
getDefaultActiveButtonIndex,
|
getDefaultActiveButtonIndex,
|
||||||
getEstimatedGasPrices,
|
getEstimatedGasPrices,
|
||||||
getEstimatedGasTimes,
|
getEstimatedGasTimes,
|
||||||
|
getGasEstimatesLoadingStatus,
|
||||||
getPriceAndTimeEstimates,
|
getPriceAndTimeEstimates,
|
||||||
getRenderableBasicEstimateData,
|
getRenderableBasicEstimateData,
|
||||||
getRenderableEstimateDataForSmallButtonsFromGWEI,
|
getRenderableEstimateDataForSmallButtonsFromGWEI,
|
||||||
@ -63,6 +64,10 @@ function getBasicGasEstimateLoadingStatus (state) {
|
|||||||
return state.gas.basicEstimateIsLoading
|
return state.gas.basicEstimateIsLoading
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGasEstimatesLoadingStatus (state) {
|
||||||
|
return state.gas.gasEstimatesLoading
|
||||||
|
}
|
||||||
|
|
||||||
function getPriceAndTimeEstimates (state) {
|
function getPriceAndTimeEstimates (state) {
|
||||||
return state.gas.priceAndTimeEstimates
|
return state.gas.priceAndTimeEstimates
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user