aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/pages/settings/advanced-tab/advanced-tab.component.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/pages/settings/advanced-tab/advanced-tab.component.js')
-rw-r--r--ui/app/pages/settings/advanced-tab/advanced-tab.component.js378
1 files changed, 378 insertions, 0 deletions
diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js
new file mode 100644
index 000000000..d1cad1746
--- /dev/null
+++ b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js
@@ -0,0 +1,378 @@
+import React, { PureComponent } from 'react'
+import PropTypes from 'prop-types'
+import validUrl from 'valid-url'
+import { exportAsFile } from '../../../helpers/utils/util'
+import ToggleButton from 'react-toggle-button'
+import TextField from '../../../components/ui/text-field'
+import Button from '../../../components/ui/button'
+import { MOBILE_SYNC_ROUTE } from '../../../helpers/constants/routes'
+
+export default class AdvancedTab extends PureComponent {
+ static contextTypes = {
+ t: PropTypes.func,
+ metricsEvent: PropTypes.func,
+ }
+
+ static propTypes = {
+ setHexDataFeatureFlag: PropTypes.func,
+ setRpcTarget: PropTypes.func,
+ displayWarning: PropTypes.func,
+ showResetAccountConfirmationModal: PropTypes.func,
+ warning: PropTypes.string,
+ history: PropTypes.object,
+ sendHexData: PropTypes.bool,
+ setAdvancedInlineGasFeatureFlag: PropTypes.func,
+ advancedInlineGas: PropTypes.bool,
+ showFiatInTestnets: PropTypes.bool,
+ setShowFiatConversionOnTestnetsPreference: PropTypes.func.isRequired,
+ }
+
+ state = {
+ newRpc: '',
+ chainId: '',
+ showOptions: false,
+ ticker: '',
+ nickname: '',
+ }
+
+ renderNewRpcUrl () {
+ const { t } = this.context
+ const { newRpc, chainId, ticker, nickname } = this.state
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('newNetwork') }</span>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <TextField
+ type="text"
+ id="new-rpc"
+ placeholder={t('rpcURL')}
+ value={newRpc}
+ onChange={e => this.setState({ newRpc: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <TextField
+ type="text"
+ id="chainid"
+ placeholder={t('optionalChainId')}
+ value={chainId}
+ onChange={e => this.setState({ chainId: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
+ }}
+ style={{
+ display: this.state.showOptions ? null : 'none',
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <TextField
+ type="text"
+ id="ticker"
+ placeholder={t('optionalSymbol')}
+ value={ticker}
+ onChange={e => this.setState({ ticker: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
+ }}
+ style={{
+ display: this.state.showOptions ? null : 'none',
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <TextField
+ type="text"
+ id="nickname"
+ placeholder={t('optionalNickname')}
+ value={nickname}
+ onChange={e => this.setState({ nickname: e.target.value })}
+ onKeyPress={e => {
+ if (e.key === 'Enter') {
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }
+ }}
+ style={{
+ display: this.state.showOptions ? null : 'none',
+ }}
+ fullWidth
+ margin="dense"
+ />
+ <div className="flex-row flex-align-center space-between">
+ <span className="settings-tab__advanced-link"
+ onClick={e => {
+ e.preventDefault()
+ this.setState({ showOptions: !this.state.showOptions })
+ }}
+ >
+ { t(this.state.showOptions ? 'hideAdvancedOptions' : 'showAdvancedOptions') }
+ </span>
+ <button
+ className="button btn-primary settings-tab__rpc-save-button"
+ onClick={e => {
+ e.preventDefault()
+ this.validateRpc(newRpc, chainId, ticker, nickname)
+ }}
+ >
+ { t('save') }
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ validateRpc (newRpc, chainId, ticker = 'ETH', nickname) {
+ const { setRpcTarget, displayWarning } = this.props
+ if (validUrl.isWebUri(newRpc)) {
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Settings',
+ action: 'Custom RPC',
+ name: 'Success',
+ },
+ customVariables: {
+ networkId: newRpc,
+ chainId,
+ },
+ })
+ if (!!chainId && Number.isNaN(parseInt(chainId))) {
+ return displayWarning(`${this.context.t('invalidInput')} chainId`)
+ }
+
+ setRpcTarget(newRpc, chainId, ticker, nickname)
+ } else {
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Settings',
+ action: 'Custom RPC',
+ name: 'Error',
+ },
+ customVariables: {
+ networkId: newRpc,
+ chainId,
+ },
+ })
+ const appendedRpc = `http://${newRpc}`
+
+ if (validUrl.isWebUri(appendedRpc)) {
+ displayWarning(this.context.t('uriErrorMsg'))
+ } else {
+ displayWarning(this.context.t('invalidRPC'))
+ }
+ }
+ }
+
+ renderMobileSync () {
+ const { t } = this.context
+ const { history } = this.props
+//
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('syncWithMobile') }</span>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <Button
+ type="primary"
+ large
+ onClick={event => {
+ event.preventDefault()
+ history.push(MOBILE_SYNC_ROUTE)
+ }}
+ >
+ { t('syncWithMobile') }
+ </Button>
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ renderStateLogs () {
+ const { t } = this.context
+ const { displayWarning } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('stateLogs') }</span>
+ <span className="settings-page__content-description">
+ { t('stateLogsDescription') }
+ </span>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <Button
+ type="primary"
+ large
+ onClick={() => {
+ window.logStateString((err, result) => {
+ if (err) {
+ displayWarning(t('stateLogError'))
+ } else {
+ exportAsFile('MetaMask State Logs.json', result)
+ }
+ })
+ }}
+ >
+ { t('downloadStateLogs') }
+ </Button>
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ renderResetAccount () {
+ const { t } = this.context
+ const { showResetAccountConfirmationModal } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('resetAccount') }</span>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <Button
+ type="secondary"
+ large
+ className="settings-tab__button--orange"
+ onClick={event => {
+ event.preventDefault()
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Settings',
+ action: 'Reset Account',
+ name: 'Reset Account',
+ },
+ })
+ showResetAccountConfirmationModal()
+ }}
+ >
+ { t('resetAccount') }
+ </Button>
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ renderHexDataOptIn () {
+ const { t } = this.context
+ const { sendHexData, setHexDataFeatureFlag } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('showHexData') }</span>
+ <div className="settings-page__content-description">
+ { t('showHexDataDescription') }
+ </div>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <ToggleButton
+ value={sendHexData}
+ onToggle={value => setHexDataFeatureFlag(!value)}
+ activeLabel=""
+ inactiveLabel=""
+ />
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ renderAdvancedGasInputInline () {
+ const { t } = this.context
+ const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('showAdvancedGasInline') }</span>
+ <div className="settings-page__content-description">
+ { t('showAdvancedGasInlineDescription') }
+ </div>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <ToggleButton
+ value={advancedInlineGas}
+ onToggle={value => setAdvancedInlineGasFeatureFlag(!value)}
+ activeLabel=""
+ inactiveLabel=""
+ />
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ renderShowConversionInTestnets () {
+ const { t } = this.context
+ const {
+ showFiatInTestnets,
+ setShowFiatConversionOnTestnetsPreference,
+ } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('showFiatConversionInTestnets') }</span>
+ <div className="settings-page__content-description">
+ { t('showFiatConversionInTestnetsDescription') }
+ </div>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <ToggleButton
+ value={showFiatInTestnets}
+ onToggle={value => setShowFiatConversionOnTestnetsPreference(!value)}
+ activeLabel=""
+ inactiveLabel=""
+ />
+ </div>
+ </div>
+ </div>
+ )
+ }
+
+ renderContent () {
+ const { warning } = this.props
+
+ return (
+ <div className="settings-page__body">
+ { warning && <div className="settings-tab__error">{ warning }</div> }
+ { this.renderStateLogs() }
+ { this.renderMobileSync() }
+ { this.renderNewRpcUrl() }
+ { this.renderResetAccount() }
+ { this.renderAdvancedGasInputInline() }
+ { this.renderHexDataOptIn() }
+ { this.renderShowConversionInTestnets() }
+ </div>
+ )
+ }
+
+ render () {
+ return this.renderContent()
+ }
+}