aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorThomas Huang <tmashuang@users.noreply.github.com>2018-03-12 22:50:55 +0800
committerGitHub <noreply@github.com>2018-03-12 22:50:55 +0800
commitb7c7083a112ea6908e8c5990886ab388200a51f4 (patch)
treebf7e0f880b5a3ce32cd0b0e680f62e0f5068df8d /ui
parent174f57b4646b3d320850c6286189a146cf0e23b0 (diff)
parentddc85354d3df508cbecc016fc0213a6560d885e1 (diff)
downloadtangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.tar
tangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.tar.gz
tangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.tar.bz2
tangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.tar.lz
tangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.tar.xz
tangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.tar.zst
tangerine-wallet-browser-b7c7083a112ea6908e8c5990886ab388200a51f4.zip
Merge branch 'master' into i18n
Diffstat (limited to 'ui')
-rw-r--r--ui/app/accounts/import/json.js180
-rw-r--r--ui/app/actions.js125
-rw-r--r--ui/app/add-token.js16
-rw-r--r--ui/app/components/dropdowns/network-dropdown.js8
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js4
-rw-r--r--ui/app/css/itcss/components/new-account.scss2
-rw-r--r--ui/app/css/itcss/settings/variables.scss4
-rw-r--r--ui/app/keychains/hd/restore-vault.js23
-rw-r--r--ui/app/reducers/app.js14
-rw-r--r--ui/app/reducers/metamask.js2
10 files changed, 228 insertions, 150 deletions
diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js
index 791759666..93c7afdb9 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/accounts/import/json.js
@@ -1,5 +1,5 @@
-const inherits = require('util').inherits
const Component = require('react').Component
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('../../actions')
@@ -8,100 +8,124 @@ const t = require('../../../i18n')
const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts'
-module.exports = connect(mapStateToProps)(JsonImportSubview)
+class JsonImportSubview extends Component {
+ constructor (props) {
+ super(props)
-function mapStateToProps (state) {
- return {
- error: state.appState.warning,
+ this.state = {
+ file: null,
+ fileContents: '',
+ }
}
-}
-inherits(JsonImportSubview, Component)
-function JsonImportSubview () {
- Component.call(this)
-}
+ render () {
+ const { error } = this.props
+
+ return (
+ h('div.new-account-import-form__json', [
+
+ h('p', 'Used by a variety of different clients'),
+ h('a.warning', {
+ href: HELP_LINK,
+ target: '_blank',
+ }, 'File import not working? Click here!'),
+
+ h(FileInput, {
+ readAs: 'text',
+ onLoad: this.onLoad.bind(this),
+ style: {
+ margin: '20px 0px 12px 34%',
+ fontSize: '15px',
+ display: 'flex',
+ justifyContent: 'center',
+ },
+ }),
+
+ h('input.new-account-import-form__input-password', {
+ type: 'password',
+ placeholder: 'Enter password',
+ id: 'json-password-box',
+ onKeyPress: this.createKeyringOnEnter.bind(this),
+ }),
+
+ h('div.new-account-create-form__buttons', {}, [
+
+ h('button.new-account-create-form__button-cancel', {
+ onClick: () => this.props.goHome(),
+ }, [
+ 'CANCEL',
+ ]),
+
+ h('button.new-account-create-form__button-create', {
+ onClick: () => this.createNewKeychain(),
+ }, [
+ 'IMPORT',
+ ]),
-JsonImportSubview.prototype.render = function () {
- const { error } = this.props
-
- return (
- h('div.new-account-import-form__json', [
-
- h('p', t('usedByClients')),
- h('a.warning', { href: HELP_LINK, target: '_blank' }, t('fileImportFail')),
-
- h(FileInput, {
- readAs: 'text',
- onLoad: this.onLoad.bind(this),
- style: {
- margin: '20px 0px 12px 34%',
- fontSize: '15px',
- display: 'flex',
- justifyContent: 'center',
- },
- }),
-
- h('input.new-account-import-form__input-password', {
- type: 'password',
- placeholder: t('enterPassword'),
- id: 'json-password-box',
- onKeyPress: this.createKeyringOnEnter.bind(this),
- }),
-
- h('div.new-account-create-form__buttons', {}, [
-
- h('button.new-account-create-form__button-cancel.allcaps', {
- onClick: () => this.props.goHome(),
- }, [
- t('cancel'),
]),
- h('button.new-account-create-form__button-create.allcaps', {
- onClick: () => this.createNewKeychain.bind(this),
- }, [
- t('import'),
- ]),
+ error ? h('span.error', error) : null,
+ ])
+ )
+ }
- ]),
+ onLoad (event, file) {
+ this.setState({file: file, fileContents: event.target.result})
+ }
- error ? h('span.error', error) : null,
- ])
- )
-}
+ createKeyringOnEnter (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewKeychain()
+ }
+ }
-JsonImportSubview.prototype.onLoad = function (event, file) {
- this.setState({file: file, fileContents: event.target.result})
-}
+ createNewKeychain () {
+ const state = this.state
-JsonImportSubview.prototype.createKeyringOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewKeychain()
- }
-}
+ if (!state) {
+ const message = 'You must select a valid file to import.'
+ return this.props.displayWarning(message)
+ }
-JsonImportSubview.prototype.createNewKeychain = function () {
- const state = this.state
+ const { fileContents } = state
- if (!state) {
- const message = 'You must select a valid file to import.'
- return this.props.dispatch(actions.displayWarning(message))
- }
+ if (!fileContents) {
+ const message = 'You must select a file to import.'
+ return this.props.displayWarning(message)
+ }
- const { fileContents } = state
+ const passwordInput = document.getElementById('json-password-box')
+ const password = passwordInput.value
- if (!fileContents) {
- const message = t('needImportFile')
- return this.props.dispatch(actions.displayWarning(message))
+ if (!password) {
+ const message = 'You must enter a password for the selected file.'
+ return this.props.displayWarning(message)
+ }
+
+ this.props.importNewJsonAccount([ fileContents, password ])
}
+}
- const passwordInput = document.getElementById('json-password-box')
- const password = passwordInput.value
+JsonImportSubview.propTypes = {
+ error: PropTypes.string,
+ goHome: PropTypes.func,
+ displayWarning: PropTypes.func,
+ importNewJsonAccount: PropTypes.func,
+}
- if (!password) {
- const message = t('needImportPassword')
- return this.props.dispatch(actions.displayWarning(message))
+const mapStateToProps = state => {
+ return {
+ error: state.appState.warning,
}
+}
- this.props.dispatch(actions.importNewAccount('JSON File', [ fileContents, password ]))
+const mapDispatchToProps = dispatch => {
+ return {
+ goHome: () => dispatch(actions.goHome()),
+ displayWarning: warning => dispatch(actions.displayWarning(warning)),
+ importNewJsonAccount: options => dispatch(actions.importNewAccount('JSON File', options)),
+ }
}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(JsonImportSubview)
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 8b1480a79..b56265edc 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -284,20 +284,43 @@ function goHome () {
// async actions
function tryUnlockMetamask (password) {
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
dispatch(actions.unlockInProgress())
log.debug(`background.submitPassword`)
- background.submitPassword(password, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.unlockFailed(err.message))
- } else {
+
+ return new Promise((resolve, reject) => {
+ background.submitPassword(password, error => {
+ if (error) {
+ return reject(error)
+ }
+
+ resolve()
+ })
+ })
+ .then(() => {
dispatch(actions.unlockSucceeded())
+ return forceUpdateMetamaskState(dispatch)
+ })
+ .then(() => {
+ return new Promise((resolve, reject) => {
+ background.verifySeedPhrase(err => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ }
+
+ resolve()
+ })
+ })
+ })
+ .then(() => {
dispatch(actions.transitionForward())
- forceUpdateMetamaskState(dispatch)
- }
- })
+ dispatch(actions.hideLoadingIndication())
+ })
+ .catch(err => {
+ dispatch(actions.unlockFailed(err.message))
+ dispatch(actions.hideLoadingIndication())
+ })
}
}
@@ -339,46 +362,53 @@ function createNewVaultAndRestore (password, seed) {
log.debug(`background.createNewVaultAndRestore`)
return new Promise((resolve, reject) => {
- background.createNewVaultAndRestore(password, seed, (err) => {
-
- dispatch(actions.hideLoadingIndication())
-
+ background.createNewVaultAndRestore(password, seed, err => {
if (err) {
- dispatch(actions.displayWarning(err.message))
return reject(err)
}
- dispatch(actions.showAccountsPage())
resolve()
})
})
+ .then(() => dispatch(actions.unMarkPasswordForgotten()))
+ .then(() => {
+ dispatch(actions.showAccountsPage())
+ dispatch(actions.hideLoadingIndication())
+ })
+ .catch(err => {
+ dispatch(actions.displayWarning(err.message))
+ dispatch(actions.hideLoadingIndication())
+ })
}
}
function createNewVaultAndKeychain (password) {
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
log.debug(`background.createNewVaultAndKeychain`)
return new Promise((resolve, reject) => {
- background.createNewVaultAndKeychain(password, (err) => {
+ background.createNewVaultAndKeychain(password, err => {
if (err) {
dispatch(actions.displayWarning(err.message))
return reject(err)
}
+
log.debug(`background.placeSeedWords`)
+
background.placeSeedWords((err) => {
if (err) {
dispatch(actions.displayWarning(err.message))
return reject(err)
}
- dispatch(actions.hideLoadingIndication())
- forceUpdateMetamaskState(dispatch)
+
resolve()
})
})
})
-
+ .then(() => forceUpdateMetamaskState(dispatch))
+ .then(() => dispatch(actions.hideLoadingIndication()))
+ .catch(() => dispatch(actions.hideLoadingIndication()))
}
}
@@ -389,18 +419,27 @@ function revealSeedConfirmation () {
}
function requestRevealSeed (password) {
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
log.debug(`background.submitPassword`)
- background.submitPassword(password, (err) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- log.debug(`background.placeSeedWords`)
- background.placeSeedWords((err, result) => {
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.hideLoadingIndication())
- dispatch(actions.showNewVaultSeed(result))
+ return new Promise((resolve, reject) => {
+ background.submitPassword(password, err => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+
+ log.debug(`background.placeSeedWords`)
+ background.placeSeedWords((err, result) => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+
+ dispatch(actions.showNewVaultSeed(result))
+ dispatch(actions.hideLoadingIndication())
+ resolve()
+ })
})
})
}
@@ -851,11 +890,14 @@ function markPasswordForgotten () {
}
function unMarkPasswordForgotten () {
- return (dispatch) => {
- return background.unMarkPasswordForgotten(() => {
- dispatch(actions.forgotPassword(false))
- forceUpdateMetamaskState(dispatch)
+ return dispatch => {
+ return new Promise(resolve => {
+ background.unMarkPasswordForgotten(() => {
+ dispatch(actions.forgotPassword(false))
+ resolve()
+ })
})
+ .then(() => forceUpdateMetamaskState(dispatch))
}
}
@@ -1704,11 +1746,16 @@ function callBackgroundThenUpdate (method, ...args) {
function forceUpdateMetamaskState (dispatch) {
log.debug(`background.getState`)
- background.getState((err, newState) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch(actions.updateMetamaskState(newState))
+ return new Promise((resolve, reject) => {
+ background.getState((err, newState) => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+
+ dispatch(actions.updateMetamaskState(newState))
+ resolve()
+ })
})
}
diff --git a/ui/app/add-token.js b/ui/app/add-token.js
index 51c577987..b8878b772 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -71,13 +71,17 @@ AddTokenScreen.prototype.componentWillMount = function () {
}
AddTokenScreen.prototype.toggleToken = function (address, token) {
- const { selectedTokens, errors } = this.state
- const { [address]: selectedToken } = selectedTokens
+ const { selectedTokens = {}, errors } = this.state
+ const selectedTokensCopy = { ...selectedTokens }
+
+ if (address in selectedTokensCopy) {
+ delete selectedTokensCopy[address]
+ } else {
+ selectedTokensCopy[address] = token
+ }
+
this.setState({
- selectedTokens: {
- ...selectedTokens,
- [address]: selectedToken ? null : token,
- },
+ selectedTokens: selectedTokensCopy,
errors: {
...errors,
tokenSelector: null,
diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js
index 67daaa5fd..5afe730c1 100644
--- a/ui/app/components/dropdowns/network-dropdown.js
+++ b/ui/app/components/dropdowns/network-dropdown.js
@@ -115,7 +115,7 @@ NetworkDropdown.prototype.render = function () {
[
providerType === 'mainnet' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
h(NetworkDropdownIcon, {
- backgroundColor: '#038789', // $blue-lagoon
+ backgroundColor: '#29B6AF', // $java
isSelected: providerType === 'mainnet',
}),
h('span.network-name-item', {
@@ -137,7 +137,7 @@ NetworkDropdown.prototype.render = function () {
[
providerType === 'ropsten' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
h(NetworkDropdownIcon, {
- backgroundColor: '#e91550', // $crimson
+ backgroundColor: '#ff4a8d', // $wild-strawberry
isSelected: providerType === 'ropsten',
}),
h('span.network-name-item', {
@@ -159,7 +159,7 @@ NetworkDropdown.prototype.render = function () {
[
providerType === 'kovan' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
h(NetworkDropdownIcon, {
- backgroundColor: '#690496', // $purple
+ backgroundColor: '#7057ff', // $cornflower-blue
isSelected: providerType === 'kovan',
}),
h('span.network-name-item', {
@@ -181,7 +181,7 @@ NetworkDropdown.prototype.render = function () {
[
providerType === 'rinkeby' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
h(NetworkDropdownIcon, {
- backgroundColor: '#ebb33f', // $tulip-tree
+ backgroundColor: '#f6c343', // $saffron
isSelected: providerType === 'rinkeby',
}),
h('span.network-name-item', {
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index 606aca3c2..69afa8094 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -64,8 +64,8 @@ function mapDispatchToProps (dispatch, ownProps) {
updateTokenExchangeRate: () => dispatch(actions.updateTokenExchangeRate(symbol)),
editTransaction: txMeta => {
const { token: { address } } = ownProps
- const { txParams, id } = txMeta
- const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+ const { txParams = {}, id } = txMeta
+ const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data) || {}
const { params = [] } = tokenData
const { value: to } = params[0] || {}
const { value: tokenAmountInDec } = params[1] || {}
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
index c6c254ede..08cff867d 100644
--- a/ui/app/css/itcss/components/new-account.scss
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -190,7 +190,7 @@
margin-top: 39px;
display: flex;
width: 100%;
- justify-content: space-evenly;
+ justify-content: space-between;
}
&__button-cancel,
diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss
index 4c0972527..d96c1ae43 100644
--- a/ui/app/css/itcss/settings/variables.scss
+++ b/ui/app/css/itcss/settings/variables.scss
@@ -46,6 +46,10 @@ $manatee: #93949d;
$spindle: #c7ddec;
$mid-gray: #5b5d67;
$cape-cod: #38393a;
+$java: #29b6af;
+$wild-strawberry: #ff4a8d;
+$cornflower-blue: #7057ff;
+$saffron: #f6c343;
/*
Z-Indicies
diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js
index a4ed137f9..d1761f17d 100644
--- a/ui/app/keychains/hd/restore-vault.js
+++ b/ui/app/keychains/hd/restore-vault.js
@@ -107,12 +107,15 @@ RestoreVaultScreen.prototype.render = function () {
}
RestoreVaultScreen.prototype.showInitializeMenu = function () {
- this.props.dispatch(actions.unMarkPasswordForgotten())
- if (this.props.forgottenPassword) {
- this.props.dispatch(actions.backToUnlockView())
- } else {
- this.props.dispatch(actions.showInitializeMenu())
- }
+ const { dispatch, forgottenPassword } = this.props
+ dispatch(actions.unMarkPasswordForgotten())
+ .then(() => {
+ if (forgottenPassword) {
+ dispatch(actions.backToUnlockView())
+ } else {
+ dispatch(actions.showInitializeMenu())
+ }
+ })
}
RestoreVaultScreen.prototype.createOnEnter = function (event) {
@@ -150,11 +153,5 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
this.warning = null
this.props.dispatch(actions.displayWarning(this.warning))
this.props.dispatch(actions.createNewVaultAndRestore(password, seed))
- .then(() => {
- this.props.dispatch(actions.unMarkPasswordForgotten())
- })
- .catch((err) => {
- log.error(err.message)
- })
-
+ .catch(err => log.error(err.message))
}
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 4dda839a2..74a0f9299 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -138,14 +138,18 @@ function reduceApp (state, action) {
})
case actions.FORGOT_PASSWORD:
- return extend(appState, {
- currentView: {
- name: action.value ? 'restoreVault' : 'accountDetail',
- },
- transForward: false,
+ const newState = extend(appState, {
forgottenPassword: action.value,
})
+ if (action.value) {
+ newState.currentView = {
+ name: 'restoreVault',
+ }
+ }
+
+ return newState
+
case actions.SHOW_INIT_MENU:
return extend(appState, {
currentView: defaultView,
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index cddcd0c1f..029d830ec 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -130,8 +130,6 @@ function reduceMetamask (state, action) {
case actions.SHOW_NEW_VAULT_SEED:
return extend(metamaskState, {
- isUnlocked: true,
- isInitialized: false,
isRevealingSeedWords: true,
seedWords: action.value,
})