From 7ffea926f23b2542c5182df7958defcdd9398b04 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 13:32:04 -0330 Subject: [PATCH] Add loading spinners when waiting for APIs in the gas customization modal --- .../advanced-tab-content.component.js | 8 +++++++- .../advanced-tab-content-component.test.js | 17 +++++++++++++++++ .../basic-tab-content.component.js | 16 +++++++++++----- .../tests/basic-tab-content-component.test.js | 11 +++++++++++ .../gas-modal-page-container.component.js | 2 ++ .../gas-modal-page-container.container.js | 4 ++++ .../gas-modal-page-container-component.test.js | 2 ++ .../gas-modal-page-container-container.test.js | 2 ++ ui/app/selectors/custom-gas.js | 5 +++++ 9 files changed, 61 insertions(+), 6 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 23945483d..ac68b833c 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' +import Loading from '../../../loading-screen' import GasPriceChart from '../../gas-price-chart' export default class AdvancedTabContent extends Component { @@ -13,6 +14,7 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + gasEstimatesLoading: PropTypes.bool, millisecondsRemaining: PropTypes.number, totalFee: PropTypes.string, timeRemaining: PropTypes.string, @@ -98,6 +100,7 @@ export default class AdvancedTabContent extends Component { insufficientBalance, totalFee, gasChartProps, + gasEstimatesLoading, } = this.props return ( @@ -112,7 +115,10 @@ export default class AdvancedTabContent extends Component { insufficientBalance ) }
Live Gas Price Predictions
- + {!gasEstimatesLoading + ? + : + }
Slower Faster diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 0c25874bb..f321ca696 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -5,6 +5,7 @@ import sinon from 'sinon' import AdvancedTabContent from '../advanced-tab-content.component.js' import GasPriceChart from '../../../gas-price-chart' +import Loading from '../../../../loading-screen' const propsMethodSpies = { updateCustomGasPrice: sinon.spy(), @@ -60,6 +61,22 @@ describe('AdvancedTabContent Component', function () { 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', () => { assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js index 4483b71df..264d038da 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import Loading from '../../../loading-screen' import GasPriceButtonGroup from '../../gas-price-button-group' export default class BasicTabContent extends Component { @@ -12,15 +13,20 @@ export default class BasicTabContent extends Component { } render () { + const { gasPriceButtonGroupProps } = this.props + return (
Estimated Processing Times
Select a higher gas fee to accelerate the processing of your transaction.*
- + {!gasPriceButtonGroupProps.loading + ? + : + }
* 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.
) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js index 0c9c6ac63..25abdd997 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -4,6 +4,7 @@ import { shallow } from 'enzyme' import BasicTabContent from '../basic-tab-content.component' import GasPriceButtonGroup from '../../../gas-price-button-group/' +import Loading from '../../../../loading-screen' const mockGasPriceButtonGroupProps = { buttonDataLoading: false, @@ -60,6 +61,7 @@ describe('BasicTabContent Component', function () { noButtonActiveByDefault, showCheck, } = wrapper.find(GasPriceButtonGroup).props() + assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading) assert.equal(className, mockGasPriceButtonGroupProps.className) assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault) @@ -67,5 +69,14 @@ describe('BasicTabContent Component', function () { assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo) 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) + }) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index b5b13c849..5d8f92a59 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -68,6 +68,7 @@ export default class GasModalPageContainer extends Component { gasChartProps, currentTimeEstimate, insufficientBalance, + gasEstimatesLoading, }) { const { transactionFee } = this.props return ( @@ -81,6 +82,7 @@ export default class GasModalPageContainer extends Component { totalFee={newTotalFiat} gasChartProps={gasChartProps} insufficientBalance={insufficientBalance} + gasEstimatesLoading={gasEstimatesLoading} /> ) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 770493be0..42b96a729 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -32,6 +32,7 @@ import { formatTimeEstimate, getFastPriceEstimateInHexWEI, getBasicGasEstimateLoadingStatus, + getGasEstimatesLoadingStatus, getCustomGasLimit, getCustomGasPrice, getDefaultActiveButtonIndex, @@ -65,6 +66,8 @@ import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price const mapStateToProps = (state, ownProps) => { const { transaction = {} } = ownProps const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) + const gasEstimatesLoading = getGasEstimatesLoadingStatus(state) + const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id) const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit @@ -127,6 +130,7 @@ const mapStateToProps = (state, ownProps) => { isSpeedUp: transaction.status === 'submitted', txId: transaction.id, insufficientBalance, + gasEstimatesLoading, } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 22f2f02dd..2ba2fa9e7 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -232,6 +232,7 @@ describe('GasModalPageContainer Component', function () { customGasLimit: 456, newTotalFiat: '$0.30', currentTimeEstimate: '1 min 31 sec', + gasEstimatesLoading: 'mockGasEstimatesLoading', }) const advancedTabContentProps = renderAdvancedTabContentResult.props assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') @@ -240,6 +241,7 @@ describe('GasModalPageContainer Component', function () { assert.equal(advancedTabContentProps.customGasLimit, 456) assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') assert.equal(advancedTabContentProps.totalFee, '$0.30') + assert.equal(advancedTabContentProps.gasEstimatesLoading, 'mockGasEstimatesLoading') }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index ba2cfe282..82c6dcd69 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -80,6 +80,7 @@ describe('gas-modal-page-container container', () => { limit: 'aaaaaaaa', price: 'ffffffff', }, + gasEstimatesLoading: false, priceAndTimeEstimates: [ { gasprice: 3, expectedTime: '31' }, { gasprice: 4, expectedTime: '62' }, @@ -118,6 +119,7 @@ describe('gas-modal-page-container container', () => { defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, + gasEstimatesLoading: false, hideBasic: true, infoRowProps: { originalTotalFiat: '637.41', diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index f06fb710d..ec234500d 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -33,6 +33,7 @@ const selectors = { getDefaultActiveButtonIndex, getEstimatedGasPrices, getEstimatedGasTimes, + getGasEstimatesLoadingStatus, getPriceAndTimeEstimates, getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, @@ -63,6 +64,10 @@ function getBasicGasEstimateLoadingStatus (state) { return state.gas.basicEstimateIsLoading } +function getGasEstimatesLoadingStatus (state) { + return state.gas.gasEstimatesLoading +} + function getPriceAndTimeEstimates (state) { return state.gas.priceAndTimeEstimates }