mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Integrate gas buttons with the send screen.
This commit is contained in:
parent
7de3f22d63
commit
b567c78bca
@ -121,6 +121,9 @@
|
|||||||
"available": {
|
"available": {
|
||||||
"message": "Available"
|
"message": "Available"
|
||||||
},
|
},
|
||||||
|
"average": {
|
||||||
|
"message": "Average"
|
||||||
|
},
|
||||||
"back": {
|
"back": {
|
||||||
"message": "Back"
|
"message": "Back"
|
||||||
},
|
},
|
||||||
@ -439,6 +442,9 @@
|
|||||||
"failed": {
|
"failed": {
|
||||||
"message": "Failed"
|
"message": "Failed"
|
||||||
},
|
},
|
||||||
|
"fast": {
|
||||||
|
"message": "Fast"
|
||||||
|
},
|
||||||
"feeChartTitle": {
|
"feeChartTitle": {
|
||||||
"message": "Live Transaction Fee Predictions"
|
"message": "Live Transaction Fee Predictions"
|
||||||
},
|
},
|
||||||
@ -1023,6 +1029,9 @@
|
|||||||
"save": {
|
"save": {
|
||||||
"message": "Save"
|
"message": "Save"
|
||||||
},
|
},
|
||||||
|
"slow": {
|
||||||
|
"message": "Slow"
|
||||||
|
},
|
||||||
"saveAsCsvFile": {
|
"saveAsCsvFile": {
|
||||||
"message": "Save as CSV File"
|
"message": "Save as CSV File"
|
||||||
},
|
},
|
||||||
@ -1277,6 +1286,9 @@
|
|||||||
"transactionErrorNoContract": {
|
"transactionErrorNoContract": {
|
||||||
"message": "Trying to call a function on a non-contract address."
|
"message": "Trying to call a function on a non-contract address."
|
||||||
},
|
},
|
||||||
|
"transactionFee": {
|
||||||
|
"message": "Transaction Fee"
|
||||||
|
},
|
||||||
"transactionMemo": {
|
"transactionMemo": {
|
||||||
"message": "Transaction memo (optional)"
|
"message": "Transaction memo (optional)"
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,12 @@ export default class ButtonGroup extends PureComponent {
|
|||||||
: this.props.defaultActiveButtonIndex,
|
: this.props.defaultActiveButtonIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate (prevProps, prevState) {
|
||||||
|
if (typeof this.props.newActiveButtonIndex === 'number' && prevState.activeButtonIndex !== this.props.newActiveButtonIndex) {
|
||||||
|
this.setState({ activeButtonIndex: prevProps.newActiveButtonIndex })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleButtonClick (activeButtonIndex) {
|
handleButtonClick (activeButtonIndex) {
|
||||||
this.setState({ activeButtonIndex })
|
this.setState({ activeButtonIndex })
|
||||||
}
|
}
|
||||||
|
@ -89,16 +89,20 @@ export default class GasModalPageContainer extends Component {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
gasPriceButtonGroupProps,
|
gasPriceButtonGroupProps,
|
||||||
|
hideBasic,
|
||||||
...advancedTabProps
|
...advancedTabProps
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab name={this.context.t('basic')}>
|
{hideBasic
|
||||||
<div className="gas-modal-content">
|
? null
|
||||||
{ this.renderBasicTabContent(gasPriceButtonGroupProps) }
|
: <Tab name={this.context.t('basic')}>
|
||||||
{ this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
|
<div className="gas-modal-content">
|
||||||
</div>
|
{ this.renderBasicTabContent(gasPriceButtonGroupProps) }
|
||||||
</Tab>
|
{ this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
}
|
||||||
<Tab name={this.context.t('advanced')}>
|
<Tab name={this.context.t('advanced')}>
|
||||||
<div className="gas-modal-content">
|
<div className="gas-modal-content">
|
||||||
{ this.renderAdvancedTabContent(advancedTabProps) }
|
{ this.renderAdvancedTabContent(advancedTabProps) }
|
||||||
|
@ -10,6 +10,9 @@ import {
|
|||||||
setCustomGasPrice,
|
setCustomGasPrice,
|
||||||
setCustomGasLimit,
|
setCustomGasLimit,
|
||||||
} from '../../../ducks/gas.duck'
|
} from '../../../ducks/gas.duck'
|
||||||
|
import {
|
||||||
|
hideGasButtonGroup,
|
||||||
|
} from '../../../ducks/send.duck'
|
||||||
import {
|
import {
|
||||||
updateGasAndCalculate,
|
updateGasAndCalculate,
|
||||||
} from '../../../ducks/confirm-transaction.duck'
|
} from '../../../ducks/confirm-transaction.duck'
|
||||||
@ -59,7 +62,10 @@ const mapStateToProps = state => {
|
|||||||
|
|
||||||
const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate)
|
const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate)
|
||||||
|
|
||||||
|
const hideBasic = state.appState.modal.modalState.props.hideBasic
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
hideBasic,
|
||||||
isConfirm: isConfirm(state),
|
isConfirm: isConfirm(state),
|
||||||
customGasPriceInHex,
|
customGasPriceInHex,
|
||||||
customGasLimitInHex,
|
customGasLimitInHex,
|
||||||
@ -95,6 +101,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
|
updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
|
||||||
return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
|
return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
|
||||||
},
|
},
|
||||||
|
hideGasButtonGroup: () => dispatch(hideGasButtonGroup()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +109,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
const { gasPriceButtonGroupProps, isConfirm } = stateProps
|
const { gasPriceButtonGroupProps, isConfirm } = stateProps
|
||||||
const {
|
const {
|
||||||
updateCustomGasPrice: dispatchUpdateCustomGasPrice,
|
updateCustomGasPrice: dispatchUpdateCustomGasPrice,
|
||||||
|
hideGasButtonGroup: dispatchHideGasButtonGroup,
|
||||||
setGasData: dispatchSetGasData,
|
setGasData: dispatchSetGasData,
|
||||||
updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate,
|
updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate,
|
||||||
...otherDispatchProps
|
...otherDispatchProps
|
||||||
@ -111,7 +119,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
...stateProps,
|
...stateProps,
|
||||||
...otherDispatchProps,
|
...otherDispatchProps,
|
||||||
...ownProps,
|
...ownProps,
|
||||||
onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData,
|
onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => {
|
||||||
|
dispatchSetGasData(newLimit, newPrice)
|
||||||
|
dispatchHideGasButtonGroup()
|
||||||
|
},
|
||||||
gasPriceButtonGroupProps: {
|
gasPriceButtonGroupProps: {
|
||||||
...gasPriceButtonGroupProps,
|
...gasPriceButtonGroupProps,
|
||||||
handleGasPriceSelection: dispatchUpdateCustomGasPrice,
|
handleGasPriceSelection: dispatchUpdateCustomGasPrice,
|
||||||
|
@ -27,7 +27,7 @@ export default class GasPriceButtonGroup extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderButtonContent ({
|
renderButtonContent ({
|
||||||
label,
|
labelKey,
|
||||||
feeInPrimaryCurrency,
|
feeInPrimaryCurrency,
|
||||||
feeInSecondaryCurrency,
|
feeInSecondaryCurrency,
|
||||||
timeEstimate,
|
timeEstimate,
|
||||||
@ -36,7 +36,7 @@ export default class GasPriceButtonGroup extends Component {
|
|||||||
showCheck,
|
showCheck,
|
||||||
}) {
|
}) {
|
||||||
return (<div>
|
return (<div>
|
||||||
{ label && <div className={`${className}__label`}>{ label }</div> }
|
{ labelKey && <div className={`${className}__label`}>{ this.context.t(labelKey) }</div> }
|
||||||
{ feeInPrimaryCurrency && <div className={`${className}__primary-currency`}>{ feeInPrimaryCurrency }</div> }
|
{ feeInPrimaryCurrency && <div className={`${className}__primary-currency`}>{ feeInPrimaryCurrency }</div> }
|
||||||
{ feeInSecondaryCurrency && <div className={`${className}__secondary-currency`}>{ feeInSecondaryCurrency }</div> }
|
{ feeInSecondaryCurrency && <div className={`${className}__secondary-currency`}>{ feeInSecondaryCurrency }</div> }
|
||||||
{ timeEstimate && <div className={`${className}__time-estimate`}>{ timeEstimate }</div> }
|
{ timeEstimate && <div className={`${className}__time-estimate`}>{ timeEstimate }</div> }
|
||||||
@ -57,9 +57,7 @@ export default class GasPriceButtonGroup extends Component {
|
|||||||
onClick={() => handleGasPriceSelection(priceInHexWei)}
|
onClick={() => handleGasPriceSelection(priceInHexWei)}
|
||||||
key={`gas-price-button-${index}`}
|
key={`gas-price-button-${index}`}
|
||||||
>
|
>
|
||||||
{buttonDataLoading
|
{this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)}
|
||||||
? 'Loading...'
|
|
||||||
: this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)}
|
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -68,18 +66,23 @@ export default class GasPriceButtonGroup extends Component {
|
|||||||
const {
|
const {
|
||||||
gasButtonInfo,
|
gasButtonInfo,
|
||||||
defaultActiveButtonIndex = 1,
|
defaultActiveButtonIndex = 1,
|
||||||
|
newActiveButtonIndex,
|
||||||
noButtonActiveByDefault = false,
|
noButtonActiveByDefault = false,
|
||||||
|
buttonDataLoading,
|
||||||
...buttonPropsAndFlags
|
...buttonPropsAndFlags
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ButtonGroup
|
!buttonDataLoading
|
||||||
className={buttonPropsAndFlags.className}
|
? <ButtonGroup
|
||||||
defaultActiveButtonIndex={defaultActiveButtonIndex}
|
className={buttonPropsAndFlags.className}
|
||||||
noButtonActiveByDefault={noButtonActiveByDefault}
|
defaultActiveButtonIndex={defaultActiveButtonIndex}
|
||||||
>
|
newActiveButtonIndex={newActiveButtonIndex}
|
||||||
{ gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) }
|
noButtonActiveByDefault={noButtonActiveByDefault}
|
||||||
</ButtonGroup>
|
>
|
||||||
|
{ gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) }
|
||||||
|
</ButtonGroup>
|
||||||
|
: <div className={`${buttonPropsAndFlags.className}__loading-container`}>Loading...</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
height: 15.4px;
|
height: 15.4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__loading-container {
|
||||||
|
height: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
.button-group__button, .button-group__button--active {
|
.button-group__button, .button-group__button--active {
|
||||||
height: 130px;
|
height: 130px;
|
||||||
@ -58,3 +61,67 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gas-price-button-group--small {
|
||||||
|
display: flex;
|
||||||
|
justify-content: stretch;
|
||||||
|
max-width: 260px;
|
||||||
|
|
||||||
|
&__button-fiat-price {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button-label {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__primary-currency {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__secondary-currency {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__loading-container {
|
||||||
|
height: 78px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group__button, .button-group__button--active {
|
||||||
|
height: 78px;
|
||||||
|
background: white;
|
||||||
|
color: $scorpion;
|
||||||
|
padding-top: 9px;
|
||||||
|
padding-left: 8.5px;
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
&:last-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group__button--active {
|
||||||
|
color: $white;
|
||||||
|
background: $dodger-blue;
|
||||||
|
|
||||||
|
i {
|
||||||
|
&:last-child {
|
||||||
|
display: flex;
|
||||||
|
color: $curious-blue;
|
||||||
|
margin-top: 10px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -58,7 +58,8 @@ export default class PageContainer extends PureComponent {
|
|||||||
|
|
||||||
renderActiveTabContent () {
|
renderActiveTabContent () {
|
||||||
const { tabsComponent } = this.props
|
const { tabsComponent } = this.props
|
||||||
const { children } = tabsComponent.props
|
let { children } = tabsComponent.props
|
||||||
|
children = children.filter(child => child)
|
||||||
const { activeTabIndex } = this.state
|
const { activeTabIndex } = this.state
|
||||||
|
|
||||||
return children[activeTabIndex]
|
return children[activeTabIndex]
|
||||||
|
@ -46,11 +46,10 @@ export default class GasFeeDisplay extends Component {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<button
|
<button
|
||||||
className="sliders-icon-container"
|
className="gas-fee-reset"
|
||||||
onClick={onClick}
|
onClick={showGasButtonGroup}
|
||||||
disabled={!gasTotal && !gasLoadingError}
|
|
||||||
>
|
>
|
||||||
<i className="fa fa-sliders sliders-icon" />
|
Reset
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react'
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import SendRowWrapper from '../send-row-wrapper/'
|
import SendRowWrapper from '../send-row-wrapper/'
|
||||||
import GasFeeDisplay from './gas-fee-display/gas-fee-display.component'
|
import GasFeeDisplay from './gas-fee-display/gas-fee-display.component'
|
||||||
|
import GasPriceButtonGroup from '../../../gas-customization/gas-price-button-group'
|
||||||
|
|
||||||
export default class SendGasRow extends Component {
|
export default class SendGasRow extends Component {
|
||||||
|
|
||||||
@ -26,21 +27,37 @@ export default class SendGasRow extends Component {
|
|||||||
gasTotal,
|
gasTotal,
|
||||||
gasFeeError,
|
gasFeeError,
|
||||||
showCustomizeGasModal,
|
showCustomizeGasModal,
|
||||||
|
gasPriceButtonGroupProps,
|
||||||
|
gasButtonGroupShown,
|
||||||
|
showGasButtonGroup
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SendRowWrapper
|
<SendRowWrapper
|
||||||
label={`${this.context.t('gasFee')}:`}
|
label={`${this.context.t('transactionFee')}:`}
|
||||||
showError={gasFeeError}
|
showError={gasFeeError}
|
||||||
errorType={'gasFee'}
|
errorType={'gasFee'}
|
||||||
>
|
>
|
||||||
<GasFeeDisplay
|
{gasButtonGroupShown
|
||||||
conversionRate={conversionRate}
|
? <div>
|
||||||
convertedCurrency={convertedCurrency}
|
<GasPriceButtonGroup
|
||||||
gasLoadingError={gasLoadingError}
|
className="gas-price-button-group--small"
|
||||||
gasTotal={gasTotal}
|
showCheck={false}
|
||||||
onClick={() => showCustomizeGasModal()}
|
{...this.props.gasPriceButtonGroupProps}
|
||||||
/>
|
/>
|
||||||
|
<div className="advanced-gas-options-btn" onClick={() => showCustomizeGasModal()}>
|
||||||
|
Advanced Options
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: <GasFeeDisplay
|
||||||
|
conversionRate={conversionRate}
|
||||||
|
convertedCurrency={convertedCurrency}
|
||||||
|
gasLoadingError={gasLoadingError}
|
||||||
|
gasTotal={gasTotal}
|
||||||
|
showGasButtonGroup={showGasButtonGroup}
|
||||||
|
onClick={() => showCustomizeGasModal()}
|
||||||
|
/>}
|
||||||
|
|
||||||
</SendRowWrapper>
|
</SendRowWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,25 +3,64 @@ import {
|
|||||||
getConversionRate,
|
getConversionRate,
|
||||||
getCurrentCurrency,
|
getCurrentCurrency,
|
||||||
getGasTotal,
|
getGasTotal,
|
||||||
|
getGasPrice,
|
||||||
} from '../../send.selectors.js'
|
} from '../../send.selectors.js'
|
||||||
import { getGasLoadingError, gasFeeIsInError } from './send-gas-row.selectors.js'
|
import{
|
||||||
import { showModal } from '../../../../actions'
|
getBasicGasEstimateLoadingStatus,
|
||||||
|
getRenderableEstimateDataForSmallButtons,
|
||||||
|
getDefaultActiveButtonIndex
|
||||||
|
} from '../../../../selectors/custom-gas'
|
||||||
|
import{
|
||||||
|
showGasButtonGroup
|
||||||
|
} from '../../../../ducks/send.duck'
|
||||||
|
import { getGasLoadingError, gasFeeIsInError, getGasButtonGroupShown } from './send-gas-row.selectors.js'
|
||||||
|
import { showModal, setGasPrice } from '../../../../actions'
|
||||||
import SendGasRow from './send-gas-row.component'
|
import SendGasRow from './send-gas-row.component'
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(SendGasRow)
|
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(SendGasRow)
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
|
const gasButtonInfo = getRenderableEstimateDataForSmallButtons(state)
|
||||||
|
const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, getGasPrice(state))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
conversionRate: getConversionRate(state),
|
conversionRate: getConversionRate(state),
|
||||||
convertedCurrency: getCurrentCurrency(state),
|
convertedCurrency: getCurrentCurrency(state),
|
||||||
gasTotal: getGasTotal(state),
|
gasTotal: getGasTotal(state),
|
||||||
gasFeeError: gasFeeIsInError(state),
|
gasFeeError: gasFeeIsInError(state),
|
||||||
gasLoadingError: getGasLoadingError(state),
|
gasLoadingError: getGasLoadingError(state),
|
||||||
|
gasPriceButtonGroupProps: {
|
||||||
|
buttonDataLoading: getBasicGasEstimateLoadingStatus(state),
|
||||||
|
defaultActiveButtonIndex: 1,
|
||||||
|
newActiveButtonIndex: activeButtonIndex > -1 ? activeButtonIndex : null,
|
||||||
|
gasButtonInfo,
|
||||||
|
},
|
||||||
|
gasButtonGroupShown: getGasButtonGroupShown(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapDispatchToProps (dispatch) {
|
function mapDispatchToProps (dispatch) {
|
||||||
return {
|
return {
|
||||||
showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS' })),
|
showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })),
|
||||||
|
setGasPrice: newPrice => dispatch(setGasPrice(newPrice)),
|
||||||
|
showGasButtonGroup: () => dispatch(showGasButtonGroup())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mergeProps (stateProps, dispatchProps, ownProps) {
|
||||||
|
const { gasPriceButtonGroupProps } = stateProps
|
||||||
|
const {
|
||||||
|
setGasPrice: dispatchSetGasPrice,
|
||||||
|
...otherDispatchProps
|
||||||
|
} = dispatchProps
|
||||||
|
|
||||||
|
return {
|
||||||
|
...stateProps,
|
||||||
|
...otherDispatchProps,
|
||||||
|
...ownProps,
|
||||||
|
gasPriceButtonGroupProps: {
|
||||||
|
...gasPriceButtonGroupProps,
|
||||||
|
handleGasPriceSelection: dispatchSetGasPrice,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
const selectors = {
|
const selectors = {
|
||||||
gasFeeIsInError,
|
gasFeeIsInError,
|
||||||
getGasLoadingError,
|
getGasLoadingError,
|
||||||
|
getGasButtonGroupShown,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = selectors
|
module.exports = selectors
|
||||||
@ -12,3 +13,7 @@ function getGasLoadingError (state) {
|
|||||||
function gasFeeIsInError (state) {
|
function gasFeeIsInError (state) {
|
||||||
return Boolean(state.send.errors.gasFee)
|
return Boolean(state.send.errors.gasFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGasButtonGroupShown (state) {
|
||||||
|
return state.send.gasButtonGroupShown
|
||||||
|
}
|
||||||
|
@ -579,7 +579,7 @@
|
|||||||
font-family: Roboto;
|
font-family: Roboto;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
width: 88px;
|
width: 112px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
@ -622,6 +622,7 @@
|
|||||||
|
|
||||||
&__to-autocomplete {
|
&__to-autocomplete {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: 260px;
|
||||||
|
|
||||||
&__down-caret {
|
&__down-caret {
|
||||||
z-index: 1026;
|
z-index: 1026;
|
||||||
@ -684,6 +685,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__sliders-icon-container {
|
&__sliders-icon-container {
|
||||||
@ -917,6 +919,15 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.advanced-gas-options-btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2f9ae0;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sliders-icon-container {
|
.sliders-icon-container {
|
||||||
@ -935,6 +946,23 @@
|
|||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gas-fee-reset {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
right: 12px;
|
||||||
|
top: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2f9ae0;
|
||||||
|
font-family: Roboto;
|
||||||
|
}
|
||||||
|
|
||||||
.sliders-icon {
|
.sliders-icon {
|
||||||
color: $curious-blue;
|
color: $curious-blue;
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,14 @@ const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN'
|
|||||||
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN'
|
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN'
|
||||||
const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS'
|
const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS'
|
||||||
const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE'
|
const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE'
|
||||||
|
const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP'
|
||||||
|
const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP'
|
||||||
|
|
||||||
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
|
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
|
||||||
const initState = {
|
const initState = {
|
||||||
fromDropdownOpen: false,
|
fromDropdownOpen: false,
|
||||||
toDropdownOpen: false,
|
toDropdownOpen: false,
|
||||||
|
gasButtonGroupShown: true,
|
||||||
errors: {},
|
errors: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +46,14 @@ export default function reducer ({ send: sendState = initState }, action = {}) {
|
|||||||
...action.value,
|
...action.value,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
case SHOW_GAS_BUTTON_GROUP:
|
||||||
|
return extend(newState, {
|
||||||
|
gasButtonGroupShown: true,
|
||||||
|
})
|
||||||
|
case HIDE_GAS_BUTTON_GROUP:
|
||||||
|
return extend(newState, {
|
||||||
|
gasButtonGroupShown: false,
|
||||||
|
})
|
||||||
case RESET_SEND_STATE:
|
case RESET_SEND_STATE:
|
||||||
return extend({}, initState)
|
return extend({}, initState)
|
||||||
default:
|
default:
|
||||||
@ -67,6 +78,14 @@ export function closeToDropdown () {
|
|||||||
return { type: CLOSE_TO_DROPDOWN }
|
return { type: CLOSE_TO_DROPDOWN }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showGasButtonGroup () {
|
||||||
|
return { type: SHOW_GAS_BUTTON_GROUP }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hideGasButtonGroup () {
|
||||||
|
return { type: HIDE_GAS_BUTTON_GROUP }
|
||||||
|
}
|
||||||
|
|
||||||
export function updateSendErrors (errorObject) {
|
export function updateSendErrors (errorObject) {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_SEND_ERRORS,
|
type: UPDATE_SEND_ERRORS,
|
||||||
|
@ -25,6 +25,7 @@ const selectors = {
|
|||||||
getCustomGasLimit,
|
getCustomGasLimit,
|
||||||
getCustomGasPrice,
|
getCustomGasPrice,
|
||||||
getCustomGasTotal,
|
getCustomGasTotal,
|
||||||
|
getRenderableEstimateDataForSmallButtons,
|
||||||
getRenderableBasicEstimateData,
|
getRenderableBasicEstimateData,
|
||||||
getBasicGasEstimateLoadingStatus,
|
getBasicGasEstimateLoadingStatus,
|
||||||
getAveragePriceEstimateInHexWEI,
|
getAveragePriceEstimateInHexWEI,
|
||||||
@ -34,6 +35,8 @@ const selectors = {
|
|||||||
|
|
||||||
module.exports = selectors
|
module.exports = selectors
|
||||||
|
|
||||||
|
const NUMBER_OF_DECIMALS_SM_BTNS = 5
|
||||||
|
|
||||||
function getCustomGasErrors (state) {
|
function getCustomGasErrors (state) {
|
||||||
return state.gas.errors
|
return state.gas.errors
|
||||||
}
|
}
|
||||||
@ -60,7 +63,9 @@ function getAveragePriceEstimateInHexWEI (state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) {
|
function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) {
|
||||||
|
console.log('gasButtonInfo', gasButtonInfo)
|
||||||
return gasButtonInfo.findIndex(({ priceInHexWei }) => {
|
return gasButtonInfo.findIndex(({ priceInHexWei }) => {
|
||||||
|
console.log('priceInHexWei', priceInHexWei, '|', customGasPriceInHex)
|
||||||
return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice)
|
return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -74,23 +79,24 @@ function apiEstimateModifiedToGWEI (estimate) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function basicPriceEstimateToETHTotal (estimate, gasLimit) {
|
function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) {
|
||||||
return conversionUtil(calcGasTotal(gasLimit, estimate), {
|
return conversionUtil(calcGasTotal(gasLimit, estimate), {
|
||||||
fromNumericBase: 'hex',
|
fromNumericBase: 'hex',
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
fromDenomination: 'GWEI',
|
fromDenomination: 'GWEI',
|
||||||
numberOfDecimals: 9,
|
numberOfDecimals,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRenderableEthFee (estimate, gasLimit) {
|
function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) {
|
||||||
return pipe(
|
return pipe(
|
||||||
apiEstimateModifiedToGWEI,
|
apiEstimateModifiedToGWEI,
|
||||||
partialRight(basicPriceEstimateToETHTotal, [gasLimit]),
|
partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]),
|
||||||
formatETHFee
|
formatETHFee
|
||||||
)(estimate, gasLimit)
|
)(estimate, gasLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) {
|
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) {
|
||||||
return pipe(
|
return pipe(
|
||||||
apiEstimateModifiedToGWEI,
|
apiEstimateModifiedToGWEI,
|
||||||
@ -188,3 +194,46 @@ function getRenderableBasicEstimateData (state) {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRenderableEstimateDataForSmallButtons (state) {
|
||||||
|
if (getBasicGasEstimateLoadingStatus(state)) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state)
|
||||||
|
const conversionRate = state.metamask.conversionRate
|
||||||
|
const currentCurrency = getCurrentCurrency(state)
|
||||||
|
const {
|
||||||
|
gas: {
|
||||||
|
basicEstimates: {
|
||||||
|
safeLow,
|
||||||
|
average,
|
||||||
|
fast,
|
||||||
|
blockTime,
|
||||||
|
safeLowWait,
|
||||||
|
avgWait,
|
||||||
|
fastWait,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} = state
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
labelKey: 'fast',
|
||||||
|
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate),
|
||||||
|
feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS),
|
||||||
|
priceInHexWei: getGasPriceInHexWei(fast),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
labelKey: 'average',
|
||||||
|
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate),
|
||||||
|
feeInPrimaryCurrency: getRenderableEthFee(average, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS),
|
||||||
|
priceInHexWei: getGasPriceInHexWei(average),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
labelKey: 'slow',
|
||||||
|
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate),
|
||||||
|
feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS),
|
||||||
|
priceInHexWei: getGasPriceInHexWei(safeLow),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user