import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { exportAsFile } from '../../../helpers/utils/util'; import ToggleButton from '../../../components/ui/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 = { setUseNonceField: PropTypes.func, useNonceField: PropTypes.bool, setHexDataFeatureFlag: 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, autoLockTimeLimit: PropTypes.number, setAutoLockTimeLimit: PropTypes.func.isRequired, setShowFiatConversionOnTestnetsPreference: PropTypes.func.isRequired, threeBoxSyncingAllowed: PropTypes.bool.isRequired, setThreeBoxSyncingPermission: PropTypes.func.isRequired, threeBoxDisabled: PropTypes.bool.isRequired, setIpfsGateway: PropTypes.func.isRequired, ipfsGateway: PropTypes.string.isRequired, useLedgerLive: PropTypes.bool.isRequired, setLedgerLivePreference: PropTypes.func.isRequired, }; state = { autoLockTimeLimit: this.props.autoLockTimeLimit, lockTimeError: '', ipfsGateway: this.props.ipfsGateway, ipfsGatewayError: '', }; renderMobileSync() { const { t } = this.context; const { history } = this.props; return (
{t('syncWithMobile')}
); } renderStateLogs() { const { t } = this.context; const { displayWarning } = this.props; return (
{t('stateLogs')} {t('stateLogsDescription')}
); } renderResetAccount() { const { t } = this.context; const { showResetAccountConfirmationModal } = this.props; return (
{t('resetAccount')} {t('resetAccountDescription')}
); } renderHexDataOptIn() { const { t } = this.context; const { sendHexData, setHexDataFeatureFlag } = this.props; return (
{t('showHexData')}
{t('showHexDataDescription')}
setHexDataFeatureFlag(!value)} offLabel={t('off')} onLabel={t('on')} />
); } renderAdvancedGasInputInline() { const { t } = this.context; const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props; return (
{t('showAdvancedGasInline')}
{t('showAdvancedGasInlineDescription')}
setAdvancedInlineGasFeatureFlag(!value)} offLabel={t('off')} onLabel={t('on')} />
); } renderShowConversionInTestnets() { const { t } = this.context; const { showFiatInTestnets, setShowFiatConversionOnTestnetsPreference, } = this.props; return (
{t('showFiatConversionInTestnets')}
{t('showFiatConversionInTestnetsDescription')}
setShowFiatConversionOnTestnetsPreference(!value) } offLabel={t('off')} onLabel={t('on')} />
); } renderUseNonceOptIn() { const { t } = this.context; const { useNonceField, setUseNonceField } = this.props; return (
{this.context.t('nonceField')}
{t('nonceFieldDescription')}
setUseNonceField(!value)} offLabel={t('off')} onLabel={t('on')} />
); } handleLockChange(time) { const { t } = this.context; const autoLockTimeLimit = Math.max(Number(time), 0); this.setState(() => { let lockTimeError = ''; if (autoLockTimeLimit > 10080) { lockTimeError = t('lockTimeTooGreat'); } return { autoLockTimeLimit, lockTimeError, }; }); } renderAutoLockTimeLimit() { const { t } = this.context; const { lockTimeError } = this.state; const { autoLockTimeLimit, setAutoLockTimeLimit } = this.props; return (
{t('autoLockTimeLimit')}
{t('autoLockTimeLimitDescription')}
this.handleLockChange(e.target.value)} error={lockTimeError} fullWidth margin="dense" min={0} />
); } renderThreeBoxControl() { const { t } = this.context; const { threeBoxSyncingAllowed, setThreeBoxSyncingPermission, threeBoxDisabled, } = this.props; let allowed = threeBoxSyncingAllowed; let description = t('syncWithThreeBoxDescription'); if (threeBoxDisabled) { allowed = false; description = t('syncWithThreeBoxDisabled'); } return (
{t('syncWithThreeBox')}
{description}
{ if (!threeBoxDisabled) { setThreeBoxSyncingPermission(!value); } }} offLabel={t('off')} onLabel={t('on')} />
); } renderLedgerLiveControl() { const { t } = this.context; const { useLedgerLive, setLedgerLivePreference } = this.props; return (
{t('ledgerLiveAdvancedSetting')}
{t('ledgerLiveAdvancedSettingDescription')}
setLedgerLivePreference(!value)} offLabel={t('off')} onLabel={t('on')} />
); } handleIpfsGatewayChange(url) { const { t } = this.context; this.setState(() => { let ipfsGatewayError = ''; try { const urlObj = new URL(addUrlProtocolPrefix(url)); if (!urlObj.host) { throw new Error(); } // don't allow the use of this gateway if (urlObj.host === 'gateway.ipfs.io') { throw new Error('Forbidden gateway'); } } catch (error) { ipfsGatewayError = error.message === 'Forbidden gateway' ? t('forbiddenIpfsGateway') : t('invalidIpfsGateway'); } return { ipfsGateway: url, ipfsGatewayError, }; }); } handleIpfsGatewaySave() { const url = new URL(addUrlProtocolPrefix(this.state.ipfsGateway)); const { host } = url; this.props.setIpfsGateway(host); } renderIpfsGatewayControl() { const { t } = this.context; const { ipfsGatewayError } = this.state; return (
{t('ipfsGateway')}
{t('ipfsGatewayDescription')}
this.handleIpfsGatewayChange(e.target.value)} error={ipfsGatewayError} fullWidth margin="dense" />
); } render() { const { warning } = this.props; return (
{warning &&
{warning}
} {this.renderStateLogs()} {this.renderMobileSync()} {this.renderResetAccount()} {this.renderAdvancedGasInputInline()} {this.renderHexDataOptIn()} {this.renderShowConversionInTestnets()} {this.renderUseNonceOptIn()} {this.renderAutoLockTimeLimit()} {this.renderThreeBoxControl()} {this.renderIpfsGatewayControl()} {this.renderLedgerLiveControl()}
); } } function addUrlProtocolPrefix(urlString) { if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) { return `https://${urlString}`; } return urlString; }