parent
8f3b762461
commit
2c032e0df4
@ -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 h = require('react-hyperscript') |
||||||
const inherits = require('util').inherits |
const classnames = require('classnames') |
||||||
|
|
||||||
module.exports = TabBar |
class TabBar extends Component { |
||||||
|
constructor (props) { |
||||||
|
super(props) |
||||||
|
const { defaultTab, tabs } = props |
||||||
|
|
||||||
inherits(TabBar, Component) |
this.state = { |
||||||
function TabBar () { |
subview: defaultTab || tabs[0].key, |
||||||
Component.call(this) |
} |
||||||
} |
} |
||||||
|
|
||||||
TabBar.prototype.render = function () { |
render () { |
||||||
const props = this.props |
const { tabs = [], tabSelected } = this.props |
||||||
const state = this.state || {} |
const { subview } = this.state |
||||||
const { tabs = [], defaultTab, tabSelected } = props |
|
||||||
const { subview = defaultTab } = state |
|
||||||
|
|
||||||
return ( |
return ( |
||||||
h('.flex-row.space-around.text-transform-uppercase', { |
h('.tab-bar', {}, [ |
||||||
style: { |
tabs.map((tab) => { |
||||||
background: '#EBEBEB', |
const { key, content } = tab |
||||||
color: '#AEAEAE', |
return h('div', { |
||||||
paddingTop: '4px', |
className: classnames('tab-bar__tab pointer', { |
||||||
minHeight: '30px', |
'tab-bar__tab--active': subview === key, |
||||||
}, |
}), |
||||||
}, tabs.map((tab) => { |
onClick: () => { |
||||||
const { key, content } = tab |
this.setState({ subview: key }) |
||||||
return h(subview === key ? '.activeForm' : '.inactiveForm.pointer', { |
tabSelected(key) |
||||||
onClick: () => { |
}, |
||||||
this.setState({ subview: key }) |
key, |
||||||
tabSelected(key) |
}, content) |
||||||
}, |
}), |
||||||
}, content) |
h('div.tab-bar__tab.tab-bar__grow-tab'), |
||||||
})) |
]) |
||||||
) |
) |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
|
module.exports = TabBar |
||||||
|
@ -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), |
|
||||||
]) |
|
||||||
} |
|
@ -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; |
||||||
|
} |
@ -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%; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -1,59 +1,261 @@ |
|||||||
const inherits = require('util').inherits |
const { Component } = require('react') |
||||||
const Component = require('react').Component |
|
||||||
const h = require('react-hyperscript') |
const h = require('react-hyperscript') |
||||||
const connect = require('react-redux').connect |
const { connect } = require('react-redux') |
||||||
const actions = require('./actions') |
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 sortedCurrencies.map(({ quote: { code, name } }) => { |
||||||
return {} |
return { |
||||||
|
displayValue: `${code.toUpperCase()} - ${name}`, |
||||||
|
key: code, |
||||||
|
value: code, |
||||||
|
} |
||||||
|
}) |
||||||
} |
} |
||||||
|
|
||||||
inherits(AppSettingsPage, Component) |
class Settings extends Component { |
||||||
function AppSettingsPage () { |
constructor (args) { |
||||||
Component.call(this) |
super(args) |
||||||
} |
this.state = { |
||||||
|
activeTab: 'settings', |
||||||
|
newRpc: '', |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
AppSettingsPage.prototype.render = function () { |
renderTabs () { |
||||||
return ( |
return h('div.settings__tabs', [ |
||||||
|
h(TabBar, { |
||||||
|
tabs: [ |
||||||
|
{ content: 'Settings', key: 'settings' }, |
||||||
|
{ content: 'Info', key: 'info' }, |
||||||
|
], |
||||||
|
defaultTab: 'settings', |
||||||
|
tabSelected: key => this.setState({ activeTab: key }), |
||||||
|
}), |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
h('.account-detail-section.flex-column.flex-grow', [ |
renderCurrentConversion () { |
||||||
|
const { metamask: { currentCurrency, conversionDate }, setCurrentCurrency } = this.props |
||||||
|
|
||||||
// subtitle and nav
|
return h('div.settings__content-row', [ |
||||||
h('.flex-row.flex-center', [ |
h('div.settings__content-item', [ |
||||||
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { |
h('span', 'Current Conversion'), |
||||||
onClick: this.navigateToAccounts.bind(this), |
h('span.settings__content-description', `Updated ${Date(conversionDate)}`), |
||||||
}), |
|
||||||
h('h2.page-subtitle', 'Settings'), |
|
||||||
]), |
]), |
||||||
|
h('div.settings__content-item', [ |
||||||
|
h('div.settings__content-item-col', [ |
||||||
|
h(SimpleDropdown, { |
||||||
|
placeholder: 'Select Currency', |
||||||
|
options: getInfuraCurrencyOptions(), |
||||||
|
selectedOption: currentCurrency, |
||||||
|
onSelect: newCurrency => setCurrentCurrency(newCurrency), |
||||||
|
}), |
||||||
|
]), |
||||||
|
]), |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
h('label', { |
renderCurrentProvider () { |
||||||
htmlFor: 'settings-rpc-endpoint', |
const { metamask: { provider = {} } } = this.props |
||||||
}, 'RPC Endpoint:'), |
let title, value, color |
||||||
h('input', { |
|
||||||
type: 'url', |
switch (provider.type) { |
||||||
id: 'settings-rpc-endpoint', |
|
||||||
onKeyPress: this.onKeyPress.bind(this), |
|
||||||
}), |
|
||||||
|
|
||||||
|
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 |
||||||
|
|
||||||
AppSettingsPage.prototype.componentDidMount = function () { |
if (validUrl.isWebUri(newRpc)) { |
||||||
document.querySelector('input').focus() |
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.onKeyPress = function (event) { |
const mapStateToProps = state => { |
||||||
// get submit event
|
return { |
||||||
if (event.key === 'Enter') { |
metamask: state.metamask, |
||||||
// this.submitPassword(event)
|
warning: state.appState.warning, |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
AppSettingsPage.prototype.navigateToAccounts = function (event) { |
const mapDispatchToProps = dispatch => { |
||||||
event.stopPropagation() |
return { |
||||||
this.props.dispatch(actions.showAccountsPage()) |
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