mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-23 02:10:12 +01:00
Merge pull request #2430 from alextsg/cb-130
[NewUI] Update settings screen to new UI
This commit is contained in:
commit
4d968fba1e
@ -21,7 +21,7 @@ const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
|
||||
const WalletView = require('./components/wallet-view')
|
||||
|
||||
// other views
|
||||
const ConfigScreen = require('./config')
|
||||
const Settings = require('./settings')
|
||||
const AddTokenScreen = require('./add-token')
|
||||
const Import = require('./accounts/import')
|
||||
const InfoScreen = require('./info')
|
||||
@ -383,7 +383,7 @@ App.prototype.renderPrimary = function () {
|
||||
|
||||
case 'config':
|
||||
log.debug('rendering config screen')
|
||||
return h(ConfigScreen, {key: 'config'})
|
||||
return h(Settings, {key: 'config'})
|
||||
|
||||
case 'import-menu':
|
||||
log.debug('rendering import screen')
|
||||
|
91
ui/app/components/dropdowns/simple-dropdown.js
Normal file
91
ui/app/components/dropdowns/simple-dropdown.js
Normal file
@ -0,0 +1,91 @@
|
||||
const { Component, PropTypes } = require('react')
|
||||
const h = require('react-hyperscript')
|
||||
const classnames = require('classnames')
|
||||
const R = require('ramda')
|
||||
|
||||
class SimpleDropdown extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
isOpen: false,
|
||||
}
|
||||
}
|
||||
|
||||
getDisplayValue () {
|
||||
const { selectedOption, options } = this.props
|
||||
const matchesOption = option => option.value === selectedOption
|
||||
const matchingOption = R.find(matchesOption)(options)
|
||||
return matchingOption
|
||||
? matchingOption.displayValue || matchingOption.value
|
||||
: selectedOption
|
||||
}
|
||||
|
||||
handleClose () {
|
||||
this.setState({ isOpen: false })
|
||||
}
|
||||
|
||||
toggleOpen () {
|
||||
const { isOpen } = this.state
|
||||
this.setState({ isOpen: !isOpen })
|
||||
}
|
||||
|
||||
renderOptions () {
|
||||
const { options, onSelect, selectedOption } = this.props
|
||||
|
||||
return h('div', [
|
||||
h('div.simple-dropdown__close-area', {
|
||||
onClick: event => {
|
||||
event.stopPropagation()
|
||||
this.handleClose()
|
||||
},
|
||||
}),
|
||||
h('div.simple-dropdown__options', [
|
||||
...options.map(option => {
|
||||
return h(
|
||||
'div.simple-dropdown__option',
|
||||
{
|
||||
className: classnames({
|
||||
'simple-dropdown__option--selected': option.value === selectedOption,
|
||||
}),
|
||||
key: option.value,
|
||||
onClick: () => {
|
||||
if (option.value !== selectedOption) {
|
||||
onSelect(option.value)
|
||||
}
|
||||
|
||||
this.handleClose()
|
||||
},
|
||||
},
|
||||
option.displayValue || option.value,
|
||||
)
|
||||
}),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
render () {
|
||||
const { placeholder } = this.props
|
||||
const { isOpen } = this.state
|
||||
|
||||
return h(
|
||||
'div.simple-dropdown',
|
||||
{
|
||||
onClick: () => this.toggleOpen(),
|
||||
},
|
||||
[
|
||||
h('div.simple-dropdown__selected', this.getDisplayValue() || placeholder || 'Select'),
|
||||
h('i.fa.fa-caret-down.fa-lg.simple-dropdown__caret'),
|
||||
isOpen && this.renderOptions(),
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SimpleDropdown.propTypes = {
|
||||
options: PropTypes.array.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
onSelect: PropTypes.func,
|
||||
selectedOption: PropTypes.string,
|
||||
}
|
||||
|
||||
module.exports = SimpleDropdown
|
@ -1,37 +1,40 @@
|
||||
const Component = require('react').Component
|
||||
const { Component } = require('react')
|
||||
const h = require('react-hyperscript')
|
||||
const inherits = require('util').inherits
|
||||
const classnames = require('classnames')
|
||||
|
||||
class TabBar extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
const { defaultTab, tabs } = props
|
||||
|
||||
this.state = {
|
||||
subview: defaultTab || tabs[0].key,
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { tabs = [], tabSelected } = this.props
|
||||
const { subview } = this.state
|
||||
|
||||
return (
|
||||
h('.tab-bar', {}, [
|
||||
tabs.map((tab) => {
|
||||
const { key, content } = tab
|
||||
return h('div', {
|
||||
className: classnames('tab-bar__tab pointer', {
|
||||
'tab-bar__tab--active': subview === key,
|
||||
}),
|
||||
onClick: () => {
|
||||
this.setState({ subview: key })
|
||||
tabSelected(key)
|
||||
},
|
||||
key,
|
||||
}, content)
|
||||
}),
|
||||
h('div.tab-bar__tab.tab-bar__grow-tab'),
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TabBar
|
||||
|
||||
inherits(TabBar, Component)
|
||||
function TabBar () {
|
||||
Component.call(this)
|
||||
}
|
||||
|
||||
TabBar.prototype.render = function () {
|
||||
const props = this.props
|
||||
const state = this.state || {}
|
||||
const { tabs = [], defaultTab, tabSelected } = props
|
||||
const { subview = defaultTab } = state
|
||||
|
||||
return (
|
||||
h('.flex-row.space-around.text-transform-uppercase', {
|
||||
style: {
|
||||
background: '#EBEBEB',
|
||||
color: '#AEAEAE',
|
||||
paddingTop: '4px',
|
||||
minHeight: '30px',
|
||||
},
|
||||
}, tabs.map((tab) => {
|
||||
const { key, content } = tab
|
||||
return h(subview === key ? '.activeForm' : '.inactiveForm.pointer', {
|
||||
onClick: () => {
|
||||
this.setState({ subview: key })
|
||||
tabSelected(key)
|
||||
},
|
||||
}, content)
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
|
215
ui/app/config.js
215
ui/app/config.js
@ -1,215 +0,0 @@
|
||||
const inherits = require('util').inherits
|
||||
const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const connect = require('react-redux').connect
|
||||
const actions = require('./actions')
|
||||
const infuraCurrencies = require('./infura-conversion.json').objects.sort((a, b) => {
|
||||
return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase())
|
||||
})
|
||||
const validUrl = require('valid-url')
|
||||
const exportAsFile = require('./util').exportAsFile
|
||||
|
||||
|
||||
module.exports = connect(mapStateToProps)(ConfigScreen)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {
|
||||
metamask: state.metamask,
|
||||
warning: state.appState.warning,
|
||||
}
|
||||
}
|
||||
|
||||
inherits(ConfigScreen, Component)
|
||||
function ConfigScreen () {
|
||||
Component.call(this)
|
||||
}
|
||||
|
||||
ConfigScreen.prototype.render = function () {
|
||||
var state = this.props
|
||||
var metamaskState = state.metamask
|
||||
var warning = state.warning
|
||||
|
||||
return (
|
||||
h('.flex-column.flex-grow', { style: { marginTop: '32px' } }, [
|
||||
|
||||
// subtitle and nav
|
||||
h('.section-title.flex-row.flex-center', [
|
||||
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
|
||||
onClick: (event) => {
|
||||
state.dispatch(actions.goHome())
|
||||
},
|
||||
}),
|
||||
h('h2.page-subtitle', 'Settings'),
|
||||
]),
|
||||
|
||||
h('.error', {
|
||||
style: {
|
||||
display: warning ? 'block' : 'none',
|
||||
padding: '0 20px',
|
||||
textAlign: 'center',
|
||||
},
|
||||
}, warning),
|
||||
|
||||
// conf view
|
||||
h('.flex-column.flex-justify-center.flex-grow.select-none', [
|
||||
h('.flex-space-around', {
|
||||
style: {
|
||||
padding: '20px',
|
||||
},
|
||||
}, [
|
||||
|
||||
currentProviderDisplay(metamaskState),
|
||||
|
||||
h('div', { style: {display: 'flex'} }, [
|
||||
h('input#new_rpc', {
|
||||
placeholder: 'New RPC URL',
|
||||
style: {
|
||||
width: 'inherit',
|
||||
flex: '1 0 auto',
|
||||
height: '30px',
|
||||
margin: '8px',
|
||||
},
|
||||
onKeyPress (event) {
|
||||
if (event.key === 'Enter') {
|
||||
var element = event.target
|
||||
var newRpc = element.value
|
||||
rpcValidation(newRpc, state)
|
||||
}
|
||||
},
|
||||
}),
|
||||
h('button', {
|
||||
style: {
|
||||
alignSelf: 'center',
|
||||
},
|
||||
onClick (event) {
|
||||
event.preventDefault()
|
||||
var element = document.querySelector('input#new_rpc')
|
||||
var newRpc = element.value
|
||||
rpcValidation(newRpc, state)
|
||||
},
|
||||
}, 'Save'),
|
||||
]),
|
||||
|
||||
h('hr.horizontal-line'),
|
||||
|
||||
currentConversionInformation(metamaskState, state),
|
||||
|
||||
h('hr.horizontal-line'),
|
||||
|
||||
h('div', {
|
||||
style: {
|
||||
marginTop: '20px',
|
||||
},
|
||||
}, [
|
||||
h('p', {
|
||||
style: {
|
||||
fontFamily: 'Montserrat Light',
|
||||
fontSize: '13px',
|
||||
},
|
||||
}, `State logs contain your public account addresses and sent transactions.`),
|
||||
h('br'),
|
||||
h('button', {
|
||||
style: {
|
||||
alignSelf: 'center',
|
||||
},
|
||||
onClick (event) {
|
||||
exportAsFile('MetaMask State Logs', window.logState())
|
||||
},
|
||||
}, 'Download State Logs'),
|
||||
]),
|
||||
|
||||
h('hr.horizontal-line'),
|
||||
|
||||
h('div', {
|
||||
style: {
|
||||
marginTop: '20px',
|
||||
},
|
||||
}, [
|
||||
h('button', {
|
||||
style: {
|
||||
alignSelf: 'center',
|
||||
},
|
||||
onClick (event) {
|
||||
event.preventDefault()
|
||||
state.dispatch(actions.revealSeedConfirmation())
|
||||
},
|
||||
}, 'Reveal Seed Words'),
|
||||
]),
|
||||
|
||||
]),
|
||||
]),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
function rpcValidation (newRpc, state) {
|
||||
if (validUrl.isWebUri(newRpc)) {
|
||||
state.dispatch(actions.setRpcTarget(newRpc))
|
||||
} else {
|
||||
var appendedRpc = `http://${newRpc}`
|
||||
if (validUrl.isWebUri(appendedRpc)) {
|
||||
state.dispatch(actions.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.'))
|
||||
} else {
|
||||
state.dispatch(actions.displayWarning('Invalid RPC URI'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function currentConversionInformation (metamaskState, state) {
|
||||
var currentCurrency = metamaskState.currentCurrency
|
||||
var conversionDate = metamaskState.conversionDate
|
||||
return h('div', [
|
||||
h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, 'Current Conversion'),
|
||||
h('span', {style: { fontWeight: 'bold', paddingRight: '10px', fontSize: '13px'}}, `Updated ${Date(conversionDate)}`),
|
||||
h('select#currentCurrency', {
|
||||
onChange (event) {
|
||||
event.preventDefault()
|
||||
var element = document.getElementById('currentCurrency')
|
||||
var newCurrency = element.value
|
||||
state.dispatch(actions.setCurrentCurrency(newCurrency))
|
||||
},
|
||||
defaultValue: currentCurrency,
|
||||
}, infuraCurrencies.map((currency) => {
|
||||
console.log(`currency`, currency);
|
||||
return h('option', {key: currency.quote.code, value: currency.quote.code}, `${currency.quote.code.toUpperCase()} - ${currency.quote.name}`)
|
||||
})
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
function currentProviderDisplay (metamaskState) {
|
||||
var provider = metamaskState.provider
|
||||
var title, value
|
||||
|
||||
switch (provider.type) {
|
||||
|
||||
case 'mainnet':
|
||||
title = 'Current Network'
|
||||
value = 'Main Ethereum Network'
|
||||
break
|
||||
|
||||
case 'ropsten':
|
||||
title = 'Current Network'
|
||||
value = 'Ropsten Test Network'
|
||||
break
|
||||
|
||||
case 'kovan':
|
||||
title = 'Current Network'
|
||||
value = 'Kovan Test Network'
|
||||
break
|
||||
|
||||
case 'rinkeby':
|
||||
title = 'Current Network'
|
||||
value = 'Rinkeby Test Network'
|
||||
break
|
||||
|
||||
default:
|
||||
title = 'Current RPC'
|
||||
value = metamaskState.provider.rpcTarget
|
||||
}
|
||||
|
||||
return h('div', [
|
||||
h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, title),
|
||||
h('span', value),
|
||||
])
|
||||
}
|
@ -38,3 +38,8 @@
|
||||
|
||||
@import './gas-slider.scss';
|
||||
|
||||
@import './settings.scss';
|
||||
|
||||
@import './tab-bar.scss';
|
||||
|
||||
@import './simple-dropdown.scss';
|
||||
|
135
ui/app/css/itcss/components/settings.scss
Normal file
135
ui/app/css/itcss/components/settings.scss
Normal file
@ -0,0 +1,135 @@
|
||||
.settings {
|
||||
position: relative;
|
||||
background: $white;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.settings__header {
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.settings__close-button::after {
|
||||
content: '\00D7';
|
||||
font-size: 40px;
|
||||
color: $dusty-gray;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.settings__error {
|
||||
padding-bottom: 20px;
|
||||
text-align: center;
|
||||
color: $crimson;
|
||||
}
|
||||
|
||||
.settings__content {
|
||||
padding: 0 25px;
|
||||
}
|
||||
|
||||
.settings__content-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 10px 0 20px;
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.settings__content-item {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 5px;
|
||||
height: 71px;
|
||||
}
|
||||
|
||||
.settings__content-item-col {
|
||||
max-width: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.settings__content-description {
|
||||
font-size: 14px;
|
||||
color: $dusty-gray;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.settings__input {
|
||||
padding-left: 10px;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.settings__input::-webkit-input-placeholder {
|
||||
font-weight: 100;
|
||||
color: $dusty-gray;
|
||||
}
|
||||
|
||||
.settings__input::-moz-placeholder {
|
||||
font-weight: 100;
|
||||
color: $dusty-gray;
|
||||
}
|
||||
|
||||
.settings__input:-ms-input-placeholder {
|
||||
font-weight: 100;
|
||||
color: $dusty-gray;
|
||||
}
|
||||
|
||||
.settings__input:-moz-placeholder {
|
||||
font-weight: 100;
|
||||
color: $dusty-gray;
|
||||
}
|
||||
|
||||
.settings__provider-wrapper {
|
||||
font-size: 16px;
|
||||
border: 1px solid $alto;
|
||||
border-radius: 2px;
|
||||
padding: 15px;
|
||||
background-color: $white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.settings__provider-icon {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
margin-right: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.settings__rpc-save-button {
|
||||
align-self: flex-end;
|
||||
padding: 5px;
|
||||
text-transform: uppercase;
|
||||
color: $dusty-gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.settings__clear-button {
|
||||
font-size: 16px;
|
||||
border: 1px solid $curious-blue;
|
||||
color: $curious-blue;
|
||||
border-radius: 2px;
|
||||
padding: 18px;
|
||||
background-color: $white;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.settings__clear-button--red {
|
||||
border: 1px solid $monzo;
|
||||
color: $monzo;
|
||||
}
|
65
ui/app/css/itcss/components/simple-dropdown.scss
Normal file
65
ui/app/css/itcss/components/simple-dropdown.scss
Normal file
@ -0,0 +1,65 @@
|
||||
.simple-dropdown {
|
||||
height: 56px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
border: 1px solid $alto;
|
||||
border-radius: 4px;
|
||||
background-color: $white;
|
||||
font-size: 16px;
|
||||
color: #4d4d4d;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.simple-dropdown__caret {
|
||||
color: $silver;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.simple-dropdown__selected {
|
||||
flex-grow: 1;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.simple-dropdown__options {
|
||||
z-index: 1050;
|
||||
position: absolute;
|
||||
height: 220px;
|
||||
width: 100%;
|
||||
border: 1px solid #d2d8dd;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
-webkit-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .11);
|
||||
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .11);
|
||||
margin-top: 10px;
|
||||
overflow-y: scroll;
|
||||
left: 0;
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
.simple-dropdown__option {
|
||||
padding: 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: $gallery;
|
||||
}
|
||||
}
|
||||
|
||||
.simple-dropdown__option--selected {
|
||||
background-color: $alto;
|
||||
|
||||
&:hover {
|
||||
background-color: $alto;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.simple-dropdown__close-area {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
23
ui/app/css/itcss/components/tab-bar.scss
Normal file
23
ui/app/css/itcss/components/tab-bar.scss
Normal file
@ -0,0 +1,23 @@
|
||||
.tab-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.tab-bar__tab {
|
||||
min-width: 0;
|
||||
flex: 0 0 auto;
|
||||
padding: 15px 25px;
|
||||
border-bottom: 1px solid $alto;
|
||||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.tab-bar__tab--active {
|
||||
border-color: $black;
|
||||
}
|
||||
|
||||
.tab-bar__grow-tab {
|
||||
flex-grow: 1;
|
||||
}
|
@ -3,7 +3,7 @@ const h = require('react-hyperscript')
|
||||
const inherits = require('util').inherits
|
||||
const AccountAndTransactionDetails = require('./account-and-transaction-details')
|
||||
const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
|
||||
const ConfigScreen = require('./config')
|
||||
const Settings = require('./settings')
|
||||
const UnlockScreen = require('./unlock')
|
||||
|
||||
module.exports = MainContainer
|
||||
@ -38,7 +38,7 @@ MainContainer.prototype.render = function () {
|
||||
case 'config':
|
||||
log.debug('rendering config screen from unlock screen.')
|
||||
contents = {
|
||||
component: ConfigScreen,
|
||||
component: Settings,
|
||||
key: 'config',
|
||||
}
|
||||
break
|
||||
|
@ -1,59 +1,261 @@
|
||||
const inherits = require('util').inherits
|
||||
const Component = require('react').Component
|
||||
const { Component } = require('react')
|
||||
const h = require('react-hyperscript')
|
||||
const connect = require('react-redux').connect
|
||||
const { connect } = require('react-redux')
|
||||
const actions = require('./actions')
|
||||
const infuraCurrencies = require('./infura-conversion.json')
|
||||
const validUrl = require('valid-url')
|
||||
const { exportAsFile } = require('./util')
|
||||
const TabBar = require('./components/tab-bar')
|
||||
const SimpleDropdown = require('./components/dropdowns/simple-dropdown')
|
||||
|
||||
module.exports = connect(mapStateToProps)(AppSettingsPage)
|
||||
const getInfuraCurrencyOptions = () => {
|
||||
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
|
||||
return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase())
|
||||
})
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {}
|
||||
return sortedCurrencies.map(({ quote: { code, name } }) => {
|
||||
return {
|
||||
displayValue: `${code.toUpperCase()} - ${name}`,
|
||||
key: code,
|
||||
value: code,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inherits(AppSettingsPage, Component)
|
||||
function AppSettingsPage () {
|
||||
Component.call(this)
|
||||
}
|
||||
class Settings extends Component {
|
||||
constructor (args) {
|
||||
super(args)
|
||||
this.state = {
|
||||
activeTab: 'settings',
|
||||
newRpc: '',
|
||||
}
|
||||
}
|
||||
|
||||
AppSettingsPage.prototype.render = function () {
|
||||
return (
|
||||
|
||||
h('.account-detail-section.flex-column.flex-grow', [
|
||||
|
||||
// subtitle and nav
|
||||
h('.flex-row.flex-center', [
|
||||
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
|
||||
onClick: this.navigateToAccounts.bind(this),
|
||||
}),
|
||||
h('h2.page-subtitle', 'Settings'),
|
||||
]),
|
||||
|
||||
h('label', {
|
||||
htmlFor: 'settings-rpc-endpoint',
|
||||
}, 'RPC Endpoint:'),
|
||||
h('input', {
|
||||
type: 'url',
|
||||
id: 'settings-rpc-endpoint',
|
||||
onKeyPress: this.onKeyPress.bind(this),
|
||||
renderTabs () {
|
||||
return h('div.settings__tabs', [
|
||||
h(TabBar, {
|
||||
tabs: [
|
||||
{ content: 'Settings', key: 'settings' },
|
||||
{ content: 'Info', key: 'info' },
|
||||
],
|
||||
defaultTab: 'settings',
|
||||
tabSelected: key => this.setState({ activeTab: key }),
|
||||
}),
|
||||
|
||||
])
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
renderCurrentConversion () {
|
||||
const { metamask: { currentCurrency, conversionDate }, setCurrentCurrency } = this.props
|
||||
|
||||
AppSettingsPage.prototype.componentDidMount = function () {
|
||||
document.querySelector('input').focus()
|
||||
}
|
||||
return h('div.settings__content-row', [
|
||||
h('div.settings__content-item', [
|
||||
h('span', 'Current Conversion'),
|
||||
h('span.settings__content-description', `Updated ${Date(conversionDate)}`),
|
||||
]),
|
||||
h('div.settings__content-item', [
|
||||
h('div.settings__content-item-col', [
|
||||
h(SimpleDropdown, {
|
||||
placeholder: 'Select Currency',
|
||||
options: getInfuraCurrencyOptions(),
|
||||
selectedOption: currentCurrency,
|
||||
onSelect: newCurrency => setCurrentCurrency(newCurrency),
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
AppSettingsPage.prototype.onKeyPress = function (event) {
|
||||
// get submit event
|
||||
if (event.key === 'Enter') {
|
||||
// this.submitPassword(event)
|
||||
renderCurrentProvider () {
|
||||
const { metamask: { provider = {} } } = this.props
|
||||
let title, value, color
|
||||
|
||||
switch (provider.type) {
|
||||
|
||||
case 'mainnet':
|
||||
title = 'Current Network'
|
||||
value = 'Main Ethereum Network'
|
||||
color = '#038789'
|
||||
break
|
||||
|
||||
case 'ropsten':
|
||||
title = 'Current Network'
|
||||
value = 'Ropsten Test Network'
|
||||
color = '#e91550'
|
||||
break
|
||||
|
||||
case 'kovan':
|
||||
title = 'Current Network'
|
||||
value = 'Kovan Test Network'
|
||||
color = '#690496'
|
||||
break
|
||||
|
||||
case 'rinkeby':
|
||||
title = 'Current Network'
|
||||
value = 'Rinkeby Test Network'
|
||||
color = '#ebb33f'
|
||||
break
|
||||
|
||||
default:
|
||||
title = 'Current RPC'
|
||||
value = provider.rpcTarget
|
||||
}
|
||||
|
||||
return h('div.settings__content-row', [
|
||||
h('div.settings__content-item', title),
|
||||
h('div.settings__content-item', [
|
||||
h('div.settings__content-item-col', [
|
||||
h('div.settings__provider-wrapper', [
|
||||
h('div.settings__provider-icon', { style: { background: color } }),
|
||||
h('div', value),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
renderNewRpcUrl () {
|
||||
return (
|
||||
h('div.settings__content-row', [
|
||||
h('div.settings__content-item', [
|
||||
h('span', 'New RPC URL'),
|
||||
]),
|
||||
h('div.settings__content-item', [
|
||||
h('div.settings__content-item-col', [
|
||||
h('input.settings__input', {
|
||||
placeholder: 'New RPC URL',
|
||||
onChange: event => this.setState({ newRpc: event.target.value }),
|
||||
onKeyPress: event => {
|
||||
if (event.key === 'Enter') {
|
||||
this.validateRpc(this.state.newRpc)
|
||||
}
|
||||
},
|
||||
}),
|
||||
h('div.settings__rpc-save-button', {
|
||||
onClick: event => {
|
||||
event.preventDefault()
|
||||
this.validateRpc(this.state.newRpc)
|
||||
},
|
||||
}, 'Save'),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
validateRpc (newRpc) {
|
||||
const { setRpcTarget, displayWarning } = this.props
|
||||
|
||||
if (validUrl.isWebUri(newRpc)) {
|
||||
setRpcTarget(newRpc)
|
||||
} else {
|
||||
const appendedRpc = `http://${newRpc}`
|
||||
|
||||
if (validUrl.isWebUri(appendedRpc)) {
|
||||
displayWarning('URIs require the appropriate HTTP/HTTPS prefix.')
|
||||
} else {
|
||||
displayWarning('Invalid RPC URI')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderStateLogs () {
|
||||
return (
|
||||
h('div.settings__content-row', [
|
||||
h('div.settings__content-item', [
|
||||
h('div', 'State Logs'),
|
||||
h(
|
||||
'div.settings__content-description',
|
||||
'State logs contain your public account addresses and sent transactions.'
|
||||
),
|
||||
]),
|
||||
h('div.settings__content-item', [
|
||||
h('div.settings__content-item-col', [
|
||||
h('button.settings__clear-button', {
|
||||
onClick (event) {
|
||||
exportAsFile('MetaMask State Logs', window.logState())
|
||||
},
|
||||
}, 'Download State Logs'),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
renderSeedWords () {
|
||||
const { revealSeedConfirmation } = this.props
|
||||
|
||||
return (
|
||||
h('div.settings__content-row', [
|
||||
h('div.settings__content-item', 'Reveal Seed Words'),
|
||||
h('div.settings__content-item', [
|
||||
h('div.settings__content-item-col', [
|
||||
h('button.settings__clear-button.settings__clear-button--red', {
|
||||
onClick (event) {
|
||||
event.preventDefault()
|
||||
revealSeedConfirmation()
|
||||
},
|
||||
}, 'Reveal Seed Words'),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
renderSettingsContent () {
|
||||
const { warning } = this.props
|
||||
|
||||
return (
|
||||
h('div.settings__content', [
|
||||
warning && h('div.settings__error', warning),
|
||||
this.renderCurrentConversion(),
|
||||
this.renderCurrentProvider(),
|
||||
this.renderNewRpcUrl(),
|
||||
this.renderStateLogs(),
|
||||
this.renderSeedWords(),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
renderInfoContent () {
|
||||
|
||||
}
|
||||
|
||||
render () {
|
||||
const { goHome } = this.props
|
||||
const { activeTab } = this.state
|
||||
|
||||
return (
|
||||
h('.main-container.settings', {}, [
|
||||
h('.settings__header', [
|
||||
h('div.settings__close-button', {
|
||||
onClick: goHome,
|
||||
}),
|
||||
this.renderTabs(),
|
||||
]),
|
||||
|
||||
activeTab === 'settings'
|
||||
? this.renderSettingsContent()
|
||||
: this.renderInfoContent(),
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AppSettingsPage.prototype.navigateToAccounts = function (event) {
|
||||
event.stopPropagation()
|
||||
this.props.dispatch(actions.showAccountsPage())
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
metamask: state.metamask,
|
||||
warning: state.appState.warning,
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
goHome: () => dispatch(actions.goHome()),
|
||||
setCurrentCurrency: currency => dispatch(actions.setCurrentCurrency(currency)),
|
||||
setRpcTarget: newRpc => dispatch(actions.setRpcTarget(newRpc)),
|
||||
displayWarning: warning => dispatch(actions.displayWarning(warning)),
|
||||
revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()),
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings)
|
||||
|
Loading…
Reference in New Issue
Block a user