From 8c4d58aa4508e3d54c3f69847347e78d09c63b97 Mon Sep 17 00:00:00 2001 From: Bruno Date: Sun, 10 Jun 2018 03:52:32 -0400 Subject: initial trezor support --- .../pages/create-account/connect-hardware.js | 234 +++++++++++++++++++++ ui/app/components/pages/create-account/index.js | 25 ++- .../components/pages/create-account/new-account.js | 2 + 3 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 ui/app/components/pages/create-account/connect-hardware.js (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js new file mode 100644 index 000000000..37b7414b3 --- /dev/null +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -0,0 +1,234 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') +const connect = require('react-redux').connect +const actions = require('../../../actions') +const genAccountLink = require('../../../../lib/account-link.js') +const log = require('loglevel') +const { DEFAULT_ROUTE } = require('../../../routes') + +class ConnectHardwareForm extends Component { + constructor (props, context) { + super(props) + this.state = { + error: null, + response: null, + btnText: 'Connect to Trezor', // Test + selectedAccount: '', + accounts: [], + } + } + + connectToTrezor () { + if (this.state.accounts.length) { + return null + } + this.setState({ btnText: 'Connecting...' }) + this.getPage() + } + + getPage (page = 1) { + this.props + .connectHardware('trezor', page) + .then(accounts => { + if (accounts.length) { + this.setState({ accounts: accounts }) + } + }) + .catch(e => { + this.setState({ btnText: 'Connect to Trezor' }) + }) + } + + unlockAccount () { + if (this.state.selectedAccount === '') { + return Promise.reject({ error: 'You need to select an account!' }) + } + log.debug('should unlock account ', this.state.selectedAccount) + return this.props.unlockTrezorAccount(this.state.selectedAccount) + } + + handleRadioChange = e => { + log.debug('Selected account with index ', e.target.value) + + this.setState({ + selectedAccount: e.target.value, + error: null, + }) + } + + renderAccounts () { + if (!this.state.accounts.length) { + return null + } + log.debug('ACCOUNTS : ', this.state.accounts) + log.debug('SELECTED?', this.state.selectedAccount) + + return h('div.hw-account-list', [ + h('div.hw-account-list__title_wrapper', [ + h('div.hw-account-list__title', {}, ['Select an Address']), + h('div.hw-account-list__device', {}, ['Trezor - ETH']), + ]), + this.state.accounts.map((a, i) => { + return h('div.hw-account-list__item', { key: a.address }, [ + h('span.hw-account-list__item__index', a.index + 1), + h('div.hw-account-list__item__radio', [ + h('input', { + type: 'radio', + name: 'selectedAccount', + id: `address-${i}`, + value: a.index, + onChange: this.handleRadioChange, + }), + h( + 'label.hw-account-list__item__label', + { + htmlFor: `address-${i}`, + }, + `${a.address.slice(0, 4)}...${a.address.slice(-4)}` + ), + ]), + h('span.hw-account-list__item__balance', `${a.balance} ETH`), + h( + 'a.hw-account-list__item__link', + { + href: genAccountLink(a.address, this.props.network), + target: '_blank', + title: this.context.t('etherscanView'), + }, + h('img', { src: 'images/popout.svg' }) + ), + ]) + }), + ]) + } + + renderPagination () { + if (!this.state.accounts.length) { + return null + } + return h('div.hw-list-pagination', [ + h( + 'button.btn-primary.hw-list-pagination__button', + { + onClick: () => this.getPage(-1), + }, + '< Prev' + ), + + h( + 'button.btn-primary.hw-list-pagination__button', + { + onClick: () => this.getPage(), + }, + 'Next >' + ), + ]) + } + + renderButtons () { + if (!this.state.accounts.length) { + return null + } + const { history } = this.props + + return h('div.new-account-create-form__buttons', {}, [ + h( + 'button.btn-default.btn--large.new-account-create-form__button', + { + onClick: () => history.push(DEFAULT_ROUTE), + }, + [this.context.t('cancel')] + ), + + h( + 'button.btn-primary.btn--large.new-account-create-form__button', + { + onClick: () => { + this.unlockAccount(this.state.selectedAccount) + .then(() => history.push(DEFAULT_ROUTE)) + .catch(e => { + this.setState({ error: e.error }) + }) + }, + }, + [this.context.t('unlock')] + ), + ]) + } + + renderError () { + return this.state.error + ? h('span.error', { style: { marginBottom: 40 } }, this.state.error) + : null + } + + renderConnectButton () { + return !this.state.accounts.length + ? h( + 'button.btn-primary.btn--large', + { onClick: () => this.connectToTrezor(), style: { margin: 12 } }, + this.state.btnText + ) + : null + } + + render () { + return h('div.new-account-create-form', [ + this.renderError(), + this.renderConnectButton(), + this.renderAccounts(), + this.renderPagination(), + this.renderButtons(), + ]) + } +} + +ConnectHardwareForm.propTypes = { + hideModal: PropTypes.func, + showImportPage: PropTypes.func, + showConnectPage: PropTypes.func, + connectHardware: PropTypes.func, + unlockTrezorAccount: PropTypes.func, + numberOfExistingAccounts: PropTypes.number, + history: PropTypes.object, + t: PropTypes.func, + network: PropTypes.string, +} + +const mapStateToProps = state => { + const { + metamask: { network, selectedAddress, identities = {} }, + } = state + const numberOfExistingAccounts = Object.keys(identities).length + + return { + network, + address: selectedAddress, + numberOfExistingAccounts, + } +} + +const mapDispatchToProps = dispatch => { + return { + toCoinbase: address => + dispatch(actions.buyEth({ network: '1', address, amount: 0 })), + hideModal: () => dispatch(actions.hideModal()), + connectHardware: (deviceName, page) => { + return dispatch(actions.connectHardware(deviceName, page)) + }, + unlockTrezorAccount: index => { + return dispatch(actions.unlockTrezorAccount(index)) + }, + showImportPage: () => dispatch(actions.showImportPage()), + showConnectPage: () => dispatch(actions.showConnectPage()), + } +} + +ConnectHardwareForm.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)( + ConnectHardwareForm +) diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js index 6e3b93742..69a4db80a 100644 --- a/ui/app/components/pages/create-account/index.js +++ b/ui/app/components/pages/create-account/index.js @@ -8,7 +8,12 @@ const { getCurrentViewContext } = require('../../../selectors') const classnames = require('classnames') const NewAccountCreateForm = require('./new-account') const NewAccountImportForm = require('./import-account') -const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE } = require('../../../routes') +const ConnectHardwareForm = require('./connect-hardware') +const { + NEW_ACCOUNT_ROUTE, + IMPORT_ACCOUNT_ROUTE, + CONNECT_HARDWARE_ROUTE, +} = require('../../../routes') class CreateAccountPage extends Component { renderTabs () { @@ -36,6 +41,19 @@ class CreateAccountPage extends Component { }, [ this.context.t('import'), ]), + h( + 'div.new-account__tabs__tab', + { + className: classnames('new-account__tabs__tab', { + 'new-account__tabs__selected': matchPath(location.pathname, { + path: CONNECT_HARDWARE_ROUTE, + exact: true, + }), + }), + onClick: () => history.push(CONNECT_HARDWARE_ROUTE), + }, + this.context.t('connect') + ), ]) } @@ -57,6 +75,11 @@ class CreateAccountPage extends Component { path: IMPORT_ACCOUNT_ROUTE, component: NewAccountImportForm, }), + h(Route, { + exact: true, + path: CONNECT_HARDWARE_ROUTE, + component: ConnectHardwareForm, + }), ]), ]), ]) diff --git a/ui/app/components/pages/create-account/new-account.js b/ui/app/components/pages/create-account/new-account.js index 9c94990e0..402b8f03b 100644 --- a/ui/app/components/pages/create-account/new-account.js +++ b/ui/app/components/pages/create-account/new-account.js @@ -62,6 +62,7 @@ class NewAccountCreateForm extends Component { NewAccountCreateForm.propTypes = { hideModal: PropTypes.func, showImportPage: PropTypes.func, + showConnectPage: PropTypes.func, createAccount: PropTypes.func, numberOfExistingAccounts: PropTypes.number, history: PropTypes.object, @@ -92,6 +93,7 @@ const mapDispatchToProps = dispatch => { }) }, showImportPage: () => dispatch(actions.showImportPage()), + showConnectPage: () => dispatch(actions.showConnectPage()), } } -- cgit From d1880073f678dbdc52e07e62ec66c39eea5062a6 Mon Sep 17 00:00:00 2001 From: Bruno Date: Sun, 10 Jun 2018 21:10:22 -0400 Subject: balances working --- .../pages/create-account/connect-hardware.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index 37b7414b3..6f1e03550 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -6,6 +6,7 @@ const actions = require('../../../actions') const genAccountLink = require('../../../../lib/account-link.js') const log = require('loglevel') const { DEFAULT_ROUTE } = require('../../../routes') +const { formatBalance } = require('../../../util') class ConnectHardwareForm extends Component { constructor (props, context) { @@ -57,10 +58,22 @@ class ConnectHardwareForm extends Component { }) } + getBalance (address) { + // Get the balance + log.debug('getBalance : ', address) + const { accounts } = this.props + const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' + log.debug('balanceValue : ', balanceValue) + const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' + log.debug('formattedBalance : ', formattedBalance) + return formattedBalance + } + renderAccounts () { if (!this.state.accounts.length) { return null } + log.debug('ACCOUNTS : ', this.state.accounts) log.debug('SELECTED?', this.state.selectedAccount) @@ -70,6 +83,7 @@ class ConnectHardwareForm extends Component { h('div.hw-account-list__device', {}, ['Trezor - ETH']), ]), this.state.accounts.map((a, i) => { + return h('div.hw-account-list__item', { key: a.address }, [ h('span.hw-account-list__item__index', a.index + 1), h('div.hw-account-list__item__radio', [ @@ -88,7 +102,7 @@ class ConnectHardwareForm extends Component { `${a.address.slice(0, 4)}...${a.address.slice(-4)}` ), ]), - h('span.hw-account-list__item__balance', `${a.balance} ETH`), + h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), h( 'a.hw-account-list__item__link', { @@ -194,16 +208,18 @@ ConnectHardwareForm.propTypes = { history: PropTypes.object, t: PropTypes.func, network: PropTypes.string, + accounts: PropTypes.object, } const mapStateToProps = state => { const { - metamask: { network, selectedAddress, identities = {} }, + metamask: { network, selectedAddress, identities = {}, accounts = [] }, } = state const numberOfExistingAccounts = Object.keys(identities).length return { network, + accounts, address: selectedAddress, numberOfExistingAccounts, } -- cgit From 8763ea898e7838d08315063b0e2181405a2ae3d5 Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 13 Jun 2018 01:32:13 -0400 Subject: move TrezorKeyring to its own package --- ui/app/components/pages/create-account/connect-hardware.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index 6f1e03550..152a4f275 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -25,10 +25,10 @@ class ConnectHardwareForm extends Component { return null } this.setState({ btnText: 'Connecting...' }) - this.getPage() + this.getPage(1) } - getPage (page = 1) { + getPage (page) { this.props .connectHardware('trezor', page) .then(accounts => { @@ -133,7 +133,7 @@ class ConnectHardwareForm extends Component { h( 'button.btn-primary.hw-list-pagination__button', { - onClick: () => this.getPage(), + onClick: () => this.getPage(1), }, 'Next >' ), -- cgit From 75581ceebe719e102b177dc20f3b9e232c48e8a4 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 21 Jun 2018 14:57:45 -0230 Subject: Show all errors on account creation screen. --- ui/app/components/pages/create-account/import-account/json.js | 2 +- ui/app/components/pages/create-account/import-account/private-key.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 1dc2ba534..955b45d74 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -114,7 +114,7 @@ class JsonImportSubview extends Component { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err)) + .catch(err => displayWarning(err.message || err)) } } diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index 5df3777da..0d8ff0db6 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -104,5 +104,5 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err)) + .catch(err => displayWarning(err.message || err)) } -- cgit From 03f17d910a17abe3fe8c8dae2ef38a66bb86f222 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 21 Jun 2018 15:53:26 -0230 Subject: Check that error is defined in import-account error catch. --- ui/app/components/pages/create-account/import-account/json.js | 2 +- ui/app/components/pages/create-account/import-account/private-key.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 955b45d74..c9d14be5f 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -114,7 +114,7 @@ class JsonImportSubview extends Component { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err.message || err)) + .catch(err => err && displayWarning(err.message || err)) } } diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index 0d8ff0db6..c38c39206 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -104,5 +104,5 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err.message || err)) + .catch(err => err && displayWarning(err.message || err)) } -- cgit From f19ffaf08d49f33c395a25faf3eeb6b08d5285a4 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 2 Jul 2018 15:16:05 -0400 Subject: move hardcoded strings to localization file --- .../pages/create-account/connect-hardware.js | 24 +++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index 152a4f275..d022d7487 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -4,7 +4,6 @@ const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('../../../actions') const genAccountLink = require('../../../../lib/account-link.js') -const log = require('loglevel') const { DEFAULT_ROUTE } = require('../../../routes') const { formatBalance } = require('../../../util') @@ -14,7 +13,7 @@ class ConnectHardwareForm extends Component { this.state = { error: null, response: null, - btnText: 'Connect to Trezor', // Test + btnText: context.t('connectToTrezor'), selectedAccount: '', accounts: [], } @@ -24,7 +23,7 @@ class ConnectHardwareForm extends Component { if (this.state.accounts.length) { return null } - this.setState({ btnText: 'Connecting...' }) + this.setState({ btnText: this.context.t('connecting')}) this.getPage(1) } @@ -37,21 +36,18 @@ class ConnectHardwareForm extends Component { } }) .catch(e => { - this.setState({ btnText: 'Connect to Trezor' }) + this.setState({ btnText: this.context.t('connectToTrezor') }) }) } unlockAccount () { if (this.state.selectedAccount === '') { - return Promise.reject({ error: 'You need to select an account!' }) + return Promise.reject({ error: this.context.t('accountSelectionRequired') }) } - log.debug('should unlock account ', this.state.selectedAccount) return this.props.unlockTrezorAccount(this.state.selectedAccount) } handleRadioChange = e => { - log.debug('Selected account with index ', e.target.value) - this.setState({ selectedAccount: e.target.value, error: null, @@ -60,12 +56,9 @@ class ConnectHardwareForm extends Component { getBalance (address) { // Get the balance - log.debug('getBalance : ', address) const { accounts } = this.props const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' - log.debug('balanceValue : ', balanceValue) const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' - log.debug('formattedBalance : ', formattedBalance) return formattedBalance } @@ -74,12 +67,9 @@ class ConnectHardwareForm extends Component { return null } - log.debug('ACCOUNTS : ', this.state.accounts) - log.debug('SELECTED?', this.state.selectedAccount) - return h('div.hw-account-list', [ h('div.hw-account-list__title_wrapper', [ - h('div.hw-account-list__title', {}, ['Select an Address']), + h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), h('div.hw-account-list__device', {}, ['Trezor - ETH']), ]), this.state.accounts.map((a, i) => { @@ -127,7 +117,7 @@ class ConnectHardwareForm extends Component { { onClick: () => this.getPage(-1), }, - '< Prev' + `< ${this.context.t('prev')}` ), h( @@ -135,7 +125,7 @@ class ConnectHardwareForm extends Component { { onClick: () => this.getPage(1), }, - 'Next >' + `${this.context.t('next')} >` ), ]) } -- cgit From a8f745f9fe74751b87f500af3857b66d4c80f45e Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 2 Jul 2018 18:49:33 -0400 Subject: eslint --fix . --- ui/app/components/pages/create-account/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js index 6e3b93742..5681e43a9 100644 --- a/ui/app/components/pages/create-account/index.js +++ b/ui/app/components/pages/create-account/index.js @@ -42,7 +42,7 @@ class CreateAccountPage extends Component { render () { return h('div.new-account', {}, [ h('div.new-account__header', [ - h('div.new-account__title', this.context.t('newAccount') ), + h('div.new-account__title', this.context.t('newAccount')), this.renderTabs(), ]), h('div.new-account__form', [ -- cgit From d126887bc3a795d27f54a4ca5178503e522d41d9 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Tue, 3 Jul 2018 09:47:30 -0700 Subject: fixes 4663 --- ui/app/components/pages/create-account/import-account/json.js | 1 + ui/app/components/pages/create-account/import-account/private-key.js | 1 + 2 files changed, 2 insertions(+) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 1dc2ba534..453fceb83 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -109,6 +109,7 @@ class JsonImportSubview extends Component { .then(({ selectedAddress }) => { if (selectedAddress) { history.push(DEFAULT_ROUTE) + displayWarning(null) } else { displayWarning('Error importing account.') setSelectedAddress(firstAddress) diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index 5df3777da..7a470c2ad 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -99,6 +99,7 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { .then(({ selectedAddress }) => { if (selectedAddress) { history.push(DEFAULT_ROUTE) + displayWarning(null) } else { displayWarning('Error importing account.') setSelectedAddress(firstAddress) -- cgit From 9d3f2435e58e2454506ea1a5f7b85452a10edffa Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 3 Jul 2018 15:46:15 -0400 Subject: lint fix --- ui/app/components/pages/create-account/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js index ad2081315..d3de1ea01 100644 --- a/ui/app/components/pages/create-account/index.js +++ b/ui/app/components/pages/create-account/index.js @@ -12,7 +12,7 @@ const ConnectHardwareForm = require('./connect-hardware') const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE, - CONNECT_HARDWARE_ROUTE, + CONNECT_HARDWARE_ROUTE, } = require('../../../routes') class CreateAccountPage extends Component { -- cgit From 313090efcc5200c56373cf312052217f1a1340ef Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 5 Jul 2018 16:11:41 -0400 Subject: added message for non-chrome browsers --- .../pages/create-account/connect-hardware.js | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index d022d7487..c51b4c773 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -177,10 +177,35 @@ class ConnectHardwareForm extends Component { : null } + renderUnsupportedBrowser () { + return ( + [h('div.hw-unsupported-browser', [ + h('h3.hw-unsupported-browser__title', {}, 'Bummer! Your Browser is not supported...'), + h('p.hw-unsupported-browser__msg', {}, 'You need to use Metamask on Google Chrome in order to connect to your TREZOR device.'), + ]), + h( + 'button.btn-primary.btn--large', + { onClick: () => global.platform.openWindow({ + url: 'https://google.com/chrome', + }), style: { margin: 12 } }, + 'Download Google Chrome' + )] + ) + } + + renderConnectScreen () { + const isChrome = window.navigator.userAgent.search('Chrome') !== -1 + if (isChrome) { + return this.renderConnectButton() + } else { + return this.renderUnsupportedBrowser() + } + } + render () { return h('div.new-account-create-form', [ this.renderError(), - this.renderConnectButton(), + this.renderConnectScreen(), this.renderAccounts(), this.renderPagination(), this.renderButtons(), -- cgit From ba5cde0995f956fb22825d604fe7d664677abaaa Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 5 Jul 2018 17:04:36 -0400 Subject: move strings to localization file --- .../pages/create-account/connect-hardware.js | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index c51b4c773..1e4ee38e3 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -179,17 +179,18 @@ class ConnectHardwareForm extends Component { renderUnsupportedBrowser () { return ( - [h('div.hw-unsupported-browser', [ - h('h3.hw-unsupported-browser__title', {}, 'Bummer! Your Browser is not supported...'), - h('p.hw-unsupported-browser__msg', {}, 'You need to use Metamask on Google Chrome in order to connect to your TREZOR device.'), - ]), - h( - 'button.btn-primary.btn--large', - { onClick: () => global.platform.openWindow({ - url: 'https://google.com/chrome', - }), style: { margin: 12 } }, - 'Download Google Chrome' - )] + [ + h('div.hw-unsupported-browser', [ + h('h3.hw-unsupported-browser__title', {}, this.context.t('browserNotSupported')), + h('p.hw-unsupported-browser__msg', {}, this.context.t('chromeRequiredForTrezor')), + ]), + h( + 'button.btn-primary.btn--large', + { onClick: () => global.platform.openWindow({ + url: 'https://google.com/chrome', + }), style: { margin: 12 } }, + this.context.t('downloadGoogleChrome') + )] ) } -- cgit From 6c2730f24300449010bd3552d4d746bcb5dd176a Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 5 Jul 2018 17:45:28 -0400 Subject: Refactor UI --- .../pages/create-account/connect-hardware.js | 266 --------------------- .../connect-hardware/account-list.js | 137 +++++++++++ .../connect-hardware/connect-screen.js | 60 +++++ .../pages/create-account/connect-hardware/index.js | 131 ++++++++++ 4 files changed, 328 insertions(+), 266 deletions(-) delete mode 100644 ui/app/components/pages/create-account/connect-hardware.js create mode 100644 ui/app/components/pages/create-account/connect-hardware/account-list.js create mode 100644 ui/app/components/pages/create-account/connect-hardware/connect-screen.js create mode 100644 ui/app/components/pages/create-account/connect-hardware/index.js (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js deleted file mode 100644 index 1e4ee38e3..000000000 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ /dev/null @@ -1,266 +0,0 @@ -const { Component } = require('react') -const PropTypes = require('prop-types') -const h = require('react-hyperscript') -const connect = require('react-redux').connect -const actions = require('../../../actions') -const genAccountLink = require('../../../../lib/account-link.js') -const { DEFAULT_ROUTE } = require('../../../routes') -const { formatBalance } = require('../../../util') - -class ConnectHardwareForm extends Component { - constructor (props, context) { - super(props) - this.state = { - error: null, - response: null, - btnText: context.t('connectToTrezor'), - selectedAccount: '', - accounts: [], - } - } - - connectToTrezor () { - if (this.state.accounts.length) { - return null - } - this.setState({ btnText: this.context.t('connecting')}) - this.getPage(1) - } - - getPage (page) { - this.props - .connectHardware('trezor', page) - .then(accounts => { - if (accounts.length) { - this.setState({ accounts: accounts }) - } - }) - .catch(e => { - this.setState({ btnText: this.context.t('connectToTrezor') }) - }) - } - - unlockAccount () { - if (this.state.selectedAccount === '') { - return Promise.reject({ error: this.context.t('accountSelectionRequired') }) - } - return this.props.unlockTrezorAccount(this.state.selectedAccount) - } - - handleRadioChange = e => { - this.setState({ - selectedAccount: e.target.value, - error: null, - }) - } - - getBalance (address) { - // Get the balance - const { accounts } = this.props - const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' - const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' - return formattedBalance - } - - renderAccounts () { - if (!this.state.accounts.length) { - return null - } - - return h('div.hw-account-list', [ - h('div.hw-account-list__title_wrapper', [ - h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), - h('div.hw-account-list__device', {}, ['Trezor - ETH']), - ]), - this.state.accounts.map((a, i) => { - - return h('div.hw-account-list__item', { key: a.address }, [ - h('span.hw-account-list__item__index', a.index + 1), - h('div.hw-account-list__item__radio', [ - h('input', { - type: 'radio', - name: 'selectedAccount', - id: `address-${i}`, - value: a.index, - onChange: this.handleRadioChange, - }), - h( - 'label.hw-account-list__item__label', - { - htmlFor: `address-${i}`, - }, - `${a.address.slice(0, 4)}...${a.address.slice(-4)}` - ), - ]), - h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), - h( - 'a.hw-account-list__item__link', - { - href: genAccountLink(a.address, this.props.network), - target: '_blank', - title: this.context.t('etherscanView'), - }, - h('img', { src: 'images/popout.svg' }) - ), - ]) - }), - ]) - } - - renderPagination () { - if (!this.state.accounts.length) { - return null - } - return h('div.hw-list-pagination', [ - h( - 'button.btn-primary.hw-list-pagination__button', - { - onClick: () => this.getPage(-1), - }, - `< ${this.context.t('prev')}` - ), - - h( - 'button.btn-primary.hw-list-pagination__button', - { - onClick: () => this.getPage(1), - }, - `${this.context.t('next')} >` - ), - ]) - } - - renderButtons () { - if (!this.state.accounts.length) { - return null - } - const { history } = this.props - - return h('div.new-account-create-form__buttons', {}, [ - h( - 'button.btn-default.btn--large.new-account-create-form__button', - { - onClick: () => history.push(DEFAULT_ROUTE), - }, - [this.context.t('cancel')] - ), - - h( - 'button.btn-primary.btn--large.new-account-create-form__button', - { - onClick: () => { - this.unlockAccount(this.state.selectedAccount) - .then(() => history.push(DEFAULT_ROUTE)) - .catch(e => { - this.setState({ error: e.error }) - }) - }, - }, - [this.context.t('unlock')] - ), - ]) - } - - renderError () { - return this.state.error - ? h('span.error', { style: { marginBottom: 40 } }, this.state.error) - : null - } - - renderConnectButton () { - return !this.state.accounts.length - ? h( - 'button.btn-primary.btn--large', - { onClick: () => this.connectToTrezor(), style: { margin: 12 } }, - this.state.btnText - ) - : null - } - - renderUnsupportedBrowser () { - return ( - [ - h('div.hw-unsupported-browser', [ - h('h3.hw-unsupported-browser__title', {}, this.context.t('browserNotSupported')), - h('p.hw-unsupported-browser__msg', {}, this.context.t('chromeRequiredForTrezor')), - ]), - h( - 'button.btn-primary.btn--large', - { onClick: () => global.platform.openWindow({ - url: 'https://google.com/chrome', - }), style: { margin: 12 } }, - this.context.t('downloadGoogleChrome') - )] - ) - } - - renderConnectScreen () { - const isChrome = window.navigator.userAgent.search('Chrome') !== -1 - if (isChrome) { - return this.renderConnectButton() - } else { - return this.renderUnsupportedBrowser() - } - } - - render () { - return h('div.new-account-create-form', [ - this.renderError(), - this.renderConnectScreen(), - this.renderAccounts(), - this.renderPagination(), - this.renderButtons(), - ]) - } -} - -ConnectHardwareForm.propTypes = { - hideModal: PropTypes.func, - showImportPage: PropTypes.func, - showConnectPage: PropTypes.func, - connectHardware: PropTypes.func, - unlockTrezorAccount: PropTypes.func, - numberOfExistingAccounts: PropTypes.number, - history: PropTypes.object, - t: PropTypes.func, - network: PropTypes.string, - accounts: PropTypes.object, -} - -const mapStateToProps = state => { - const { - metamask: { network, selectedAddress, identities = {}, accounts = [] }, - } = state - const numberOfExistingAccounts = Object.keys(identities).length - - return { - network, - accounts, - address: selectedAddress, - numberOfExistingAccounts, - } -} - -const mapDispatchToProps = dispatch => { - return { - toCoinbase: address => - dispatch(actions.buyEth({ network: '1', address, amount: 0 })), - hideModal: () => dispatch(actions.hideModal()), - connectHardware: (deviceName, page) => { - return dispatch(actions.connectHardware(deviceName, page)) - }, - unlockTrezorAccount: index => { - return dispatch(actions.unlockTrezorAccount(index)) - }, - showImportPage: () => dispatch(actions.showImportPage()), - showConnectPage: () => dispatch(actions.showConnectPage()), - } -} - -ConnectHardwareForm.contextTypes = { - t: PropTypes.func, -} - -module.exports = connect(mapStateToProps, mapDispatchToProps)( - ConnectHardwareForm -) diff --git a/ui/app/components/pages/create-account/connect-hardware/account-list.js b/ui/app/components/pages/create-account/connect-hardware/account-list.js new file mode 100644 index 000000000..598865ad8 --- /dev/null +++ b/ui/app/components/pages/create-account/connect-hardware/account-list.js @@ -0,0 +1,137 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') +const genAccountLink = require('../../../../lib/account-link.js') +const { DEFAULT_ROUTE } = require('../../../routes') +const { formatBalance } = require('../../../util') + +export default class AccountList extends Component { + constructor (props, context) { + super(props) + } + + getBalance (address) { + // Get the balance + const { accounts } = this.props + const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' + const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' + return formattedBalance + } + + renderAccounts () { + if (!this.props.accounts.length) { + return null + } + + return h('div.hw-account-list', [ + h('div.hw-account-list__title_wrapper', [ + h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), + h('div.hw-account-list__device', {}, ['Trezor - ETH']), + ]), + this.props.accounts.map((a, i) => { + + return h('div.hw-account-list__item', { key: a.address }, [ + h('span.hw-account-list__item__index', a.index + 1), + h('div.hw-account-list__item__radio', [ + h('input', { + type: 'radio', + name: 'selectedAccount', + id: `address-${i}`, + value: a.index, + onChange: (e) => this.props.onAccountChange(e.target.value), + }), + h( + 'label.hw-account-list__item__label', + { + htmlFor: `address-${i}`, + }, + `${a.address.slice(0, 4)}...${a.address.slice(-4)}` + ), + ]), + h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), + h( + 'a.hw-account-list__item__link', + { + href: genAccountLink(a.address, this.props.network), + target: '_blank', + title: this.context.t('etherscanView'), + }, + h('img', { src: 'images/popout.svg' }) + ), + ]) + }), + ]) + } + + renderPagination () { + if (!this.state.accounts.length) { + return null + } + return h('div.hw-list-pagination', [ + h( + 'button.btn-primary.hw-list-pagination__button', + { + onClick: () => this.props.getPage(-1), + }, + `< ${this.context.t('prev')}` + ), + + h( + 'button.btn-primary.hw-list-pagination__button', + { + onClick: () => this.props.getPage(1), + }, + `${this.context.t('next')} >` + ), + ]) + } + + renderButtons () { + if (!this.state.accounts.length) { + return null + } + const { history } = this.props + + return h('div.new-account-create-form__buttons', {}, [ + h( + 'button.btn-default.btn--large.new-account-create-form__button', + { + onClick: () => history.push(DEFAULT_ROUTE), + }, + [this.context.t('cancel')] + ), + + h( + 'button.btn-primary.btn--large.new-account-create-form__button', + { + onClick: () => { + this.unlockAccount(this.state.selectedAccount) + .then(() => history.push(DEFAULT_ROUTE)) + .catch(e => { + this.setState({ error: e.error }) + }) + }, + }, + [this.context.t('unlock')] + ), + ]) + } + + render () { + return null + } + +} + + +AccountList.propTypes = { + accounts: PropTypes.object.isRequired, + onAccountChange: PropTypes.func.isRequired, + getPage: PropTypes.func.isRequired, + network: PropTypes.string, + history: PropTypes.object, +} + +AccountList.contextTypes = { + t: PropTypes.func, +} diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js new file mode 100644 index 000000000..1b064a15c --- /dev/null +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -0,0 +1,60 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') + +export default class ConnectScreen extends Component { + constructor (props, context) { + super(props) + } + + connectToTrezor = () => { + if (this.props.connectToTrezor) { + this.props.connectToTrezor() + } + } + + renderUnsupportedBrowser () { + return ( + [ + h('div.hw-unsupported-browser', [ + h('h3.hw-unsupported-browser__title', {}, this.context.t('browserNotSupported')), + h('p.hw-unsupported-browser__msg', {}, this.context.t('chromeRequiredForTrezor')), + ]), + h( + 'button.btn-primary.btn--large', + { onClick: () => global.platform.openWindow({ + url: 'https://google.com/chrome', + }), style: { margin: 12 } }, + this.context.t('downloadGoogleChrome') + )] + ) + } + + renderConnectButton () { + return !this.state.accounts.length + ? h( + 'button.btn-primary.btn--large', + { onClick: this.connectToTrezor, style: { margin: 12 } }, + this.props.btnText + ) + : null + } + + render () { + const isChrome = window.navigator.userAgent.search('Chrome') !== -1 + if (isChrome) { + return this.renderConnectButton() + } else { + return this.renderUnsupportedBrowser() + } + } +} + +ConnectScreen.propTypes = { + connectToTrezor: PropTypes.func.isRequired, + btnText: PropTypes.string, +} + +ConnectScreen.contextTypes = { + t: PropTypes.func, +} diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js new file mode 100644 index 000000000..04e69162f --- /dev/null +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -0,0 +1,131 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') +const connect = require('react-redux').connect +const actions = require('../../../actions') +const ConnectScreen = require('./connect-screen') +const AccountList = require('./account-list') + +class ConnectHardwareForm extends Component { + constructor (props, context) { + super(props) + this.state = { + error: null, + response: null, + btnText: context.t('connectToTrezor'), + selectedAccount: '', + accounts: [], + } + } + + connectToTrezor = () => { + if (this.state.accounts.length) { + return null + } + this.setState({ btnText: this.context.t('connecting')}) + this.getPage(1) + } + + onAccountChange = (account) => { + this.setState({selectedAccount: account, error: null}) + } + + getPage = (page) => { + this.props + .connectHardware('trezor', page) + .then(accounts => { + if (accounts.length) { + this.setState({ accounts: accounts }) + } + }) + .catch(e => { + this.setState({ btnText: this.context.t('connectToTrezor') }) + }) + } + + unlockAccount () { + if (this.state.selectedAccount === '') { + return Promise.reject({ error: this.context.t('accountSelectionRequired') }) + } + return this.props.unlockTrezorAccount(this.state.selectedAccount) + } + + + renderError () { + return this.state.error + ? h('span.error', { style: { marginBottom: 40 } }, this.state.error) + : null + } + + renderContent () { + if (!this.state.accounts.length) { + return h(ConnectScreen, { + connectToTrezor: this.connectToTrezor, + btnText: this.state.btnText, + }) + } + + return h(AccountList, { + accounts: this.state.accounts, + onAccountChange: this.onAccountChange, + network: this.props.network, + getPage: this.getPage, + history: this.props.history, + }) + } + + render () { + return h('div.new-account-create-form', [ + this.renderError(), + this.renderContent(), + ]) + } +} + +ConnectHardwareForm.propTypes = { + hideModal: PropTypes.func, + showImportPage: PropTypes.func, + showConnectPage: PropTypes.func, + connectHardware: PropTypes.func, + unlockTrezorAccount: PropTypes.func, + numberOfExistingAccounts: PropTypes.number, + history: PropTypes.object, + t: PropTypes.func, + network: PropTypes.string, + accounts: PropTypes.object, +} + +const mapStateToProps = state => { + const { + metamask: { network, selectedAddress, identities = {}, accounts = [] }, + } = state + const numberOfExistingAccounts = Object.keys(identities).length + + return { + network, + accounts, + address: selectedAddress, + numberOfExistingAccounts, + } +} + +const mapDispatchToProps = dispatch => { + return { + connectHardware: (deviceName, page) => { + return dispatch(actions.connectHardware(deviceName, page)) + }, + unlockTrezorAccount: index => { + return dispatch(actions.unlockTrezorAccount(index)) + }, + showImportPage: () => dispatch(actions.showImportPage()), + showConnectPage: () => dispatch(actions.showConnectPage()), + } +} + +ConnectHardwareForm.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)( + ConnectHardwareForm +) -- cgit From 6b2511f94f436a30c6c683f9da2c3142d9a6461c Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 5 Jul 2018 20:59:31 -0400 Subject: UI refactor --- .../connect-hardware/account-list.js | 111 ++++++++++----------- .../connect-hardware/connect-screen.js | 51 +++++----- .../pages/create-account/connect-hardware/index.js | 41 ++++++-- 3 files changed, 106 insertions(+), 97 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/account-list.js b/ui/app/components/pages/create-account/connect-hardware/account-list.js index 598865ad8..77e0af3ac 100644 --- a/ui/app/components/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/components/pages/create-account/connect-hardware/account-list.js @@ -1,11 +1,10 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -const genAccountLink = require('../../../../lib/account-link.js') -const { DEFAULT_ROUTE } = require('../../../routes') -const { formatBalance } = require('../../../util') +const genAccountLink = require('../../../../../lib/account-link.js') +const { formatBalance } = require('../../../../util') -export default class AccountList extends Component { +class AccountList extends Component { constructor (props, context) { super(props) } @@ -19,54 +18,48 @@ export default class AccountList extends Component { } renderAccounts () { - if (!this.props.accounts.length) { - return null - } - return h('div.hw-account-list', [ - h('div.hw-account-list__title_wrapper', [ - h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), - h('div.hw-account-list__device', {}, ['Trezor - ETH']), - ]), - this.props.accounts.map((a, i) => { + h('div.hw-account-list__title_wrapper', [ + h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), + h('div.hw-account-list__device', {}, ['Trezor - ETH']), + ]), + this.props.accounts.map((a, i) => { - return h('div.hw-account-list__item', { key: a.address }, [ - h('span.hw-account-list__item__index', a.index + 1), - h('div.hw-account-list__item__radio', [ - h('input', { - type: 'radio', - name: 'selectedAccount', - id: `address-${i}`, - value: a.index, - onChange: (e) => this.props.onAccountChange(e.target.value), - }), + return h('div.hw-account-list__item', { key: a.address }, [ + h('span.hw-account-list__item__index', a.index + 1), + h('div.hw-account-list__item__radio', [ + h('input', { + type: 'radio', + name: 'selectedAccount', + id: `address-${i}`, + value: a.index, + onChange: (e) => this.props.onAccountChange(e.target.value), + checked: this.props.selectedAccount === a.index.toString(), + }), + h( + 'label.hw-account-list__item__label', + { + htmlFor: `address-${i}`, + }, + `${a.address.slice(0, 4)}...${a.address.slice(-4)}` + ), + ]), + h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), h( - 'label.hw-account-list__item__label', - { - htmlFor: `address-${i}`, - }, - `${a.address.slice(0, 4)}...${a.address.slice(-4)}` + 'a.hw-account-list__item__link', + { + href: genAccountLink(a.address, this.props.network), + target: '_blank', + title: this.context.t('etherscanView'), + }, + h('img', { src: 'images/popout.svg' }) ), - ]), - h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), - h( - 'a.hw-account-list__item__link', - { - href: genAccountLink(a.address, this.props.network), - target: '_blank', - title: this.context.t('etherscanView'), - }, - h('img', { src: 'images/popout.svg' }) - ), - ]) - }), + ]) + }), ]) } renderPagination () { - if (!this.state.accounts.length) { - return null - } return h('div.hw-list-pagination', [ h( 'button.btn-primary.hw-list-pagination__button', @@ -87,30 +80,19 @@ export default class AccountList extends Component { } renderButtons () { - if (!this.state.accounts.length) { - return null - } - const { history } = this.props - return h('div.new-account-create-form__buttons', {}, [ h( 'button.btn-default.btn--large.new-account-create-form__button', { - onClick: () => history.push(DEFAULT_ROUTE), + onClick: this.props.onCancel.bind(this), }, [this.context.t('cancel')] ), h( - 'button.btn-primary.btn--large.new-account-create-form__button', + `button.btn-primary.btn--large.new-account-create-form__button ${this.props.selectedAccount === null ? '.btn-primary--disabled' : ''}`, { - onClick: () => { - this.unlockAccount(this.state.selectedAccount) - .then(() => history.push(DEFAULT_ROUTE)) - .catch(e => { - this.setState({ error: e.error }) - }) - }, + onClick: this.props.onUnlockAccount.bind(this), }, [this.context.t('unlock')] ), @@ -118,20 +100,29 @@ export default class AccountList extends Component { } render () { - return null + return h('div', {}, [ + this.renderAccounts(), + this.renderPagination(), + this.renderButtons(), + ]) } } AccountList.propTypes = { - accounts: PropTypes.object.isRequired, + accounts: PropTypes.array.isRequired, onAccountChange: PropTypes.func.isRequired, getPage: PropTypes.func.isRequired, network: PropTypes.string, + selectedAccount: PropTypes.string, history: PropTypes.object, + onUnlockAccount: PropTypes.func, + onCancel: PropTypes.func, } AccountList.contextTypes = { t: PropTypes.func, } + +module.exports = AccountList diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 1b064a15c..ec6a11b40 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -2,51 +2,43 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -export default class ConnectScreen extends Component { +class ConnectScreen extends Component { constructor (props, context) { super(props) } - connectToTrezor = () => { - if (this.props.connectToTrezor) { - this.props.connectToTrezor() - } - } - renderUnsupportedBrowser () { return ( - [ - h('div.hw-unsupported-browser', [ - h('h3.hw-unsupported-browser__title', {}, this.context.t('browserNotSupported')), - h('p.hw-unsupported-browser__msg', {}, this.context.t('chromeRequiredForTrezor')), - ]), - h( - 'button.btn-primary.btn--large', - { onClick: () => global.platform.openWindow({ - url: 'https://google.com/chrome', - }), style: { margin: 12 } }, - this.context.t('downloadGoogleChrome') - )] + h('div', {}, [ + h('div.hw-unsupported-browser', [ + h('h3.hw-unsupported-browser__title', {}, this.context.t('browserNotSupported')), + h('p.hw-unsupported-browser__msg', {}, this.context.t('chromeRequiredForTrezor')), + ]), + h( + 'button.btn-primary.btn--large', + { onClick: () => global.platform.openWindow({ + url: 'https://google.com/chrome', + }), style: { margin: 12 } }, + this.context.t('downloadGoogleChrome') + ), + ]) ) } renderConnectButton () { - return !this.state.accounts.length - ? h( - 'button.btn-primary.btn--large', - { onClick: this.connectToTrezor, style: { margin: 12 } }, - this.props.btnText - ) - : null + return h( + 'button.btn-primary.btn--large', + { onClick: this.props.connectToTrezor.bind(this), style: { margin: 12 } }, + this.props.btnText + ) } render () { const isChrome = window.navigator.userAgent.search('Chrome') !== -1 if (isChrome) { return this.renderConnectButton() - } else { - return this.renderUnsupportedBrowser() } + return this.renderUnsupportedBrowser() } } @@ -58,3 +50,6 @@ ConnectScreen.propTypes = { ConnectScreen.contextTypes = { t: PropTypes.func, } + +module.exports = ConnectScreen + diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index 04e69162f..22c54d28c 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -2,9 +2,10 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') const connect = require('react-redux').connect -const actions = require('../../../actions') +const actions = require('../../../../actions') const ConnectScreen = require('./connect-screen') const AccountList = require('./account-list') +const { DEFAULT_ROUTE } = require('../../../../routes') class ConnectHardwareForm extends Component { constructor (props, context) { @@ -13,7 +14,7 @@ class ConnectHardwareForm extends Component { error: null, response: null, btnText: context.t('connectToTrezor'), - selectedAccount: '', + selectedAccount: null, accounts: [], } } @@ -23,11 +24,11 @@ class ConnectHardwareForm extends Component { return null } this.setState({ btnText: this.context.t('connecting')}) - this.getPage(1) + this.getPage(0) } onAccountChange = (account) => { - this.setState({selectedAccount: account, error: null}) + this.setState({selectedAccount: account.toString(), error: null}) } getPage = (page) => { @@ -35,7 +36,16 @@ class ConnectHardwareForm extends Component { .connectHardware('trezor', page) .then(accounts => { if (accounts.length) { - this.setState({ accounts: accounts }) + const newState = { accounts: accounts } + // Default to the first account + if (this.state.selectedAccount === null) { + const firstAccount = accounts[0] + newState.selectedAccount = firstAccount.index.toString() + // If the page doesn't contain the selected account, let's deselect it + } else if (!accounts.filter(a => a.index.toString() === '').lenght) { + newState.selectedAccount = null + } + this.setState(newState) } }) .catch(e => { @@ -43,13 +53,23 @@ class ConnectHardwareForm extends Component { }) } - unlockAccount () { - if (this.state.selectedAccount === '') { - return Promise.reject({ error: this.context.t('accountSelectionRequired') }) + onUnlockAccount = () => { + + if (this.state.selectedAccount === null) { + this.setState({ error: this.context.t('accountSelectionRequired') }) } - return this.props.unlockTrezorAccount(this.state.selectedAccount) + + this.props.unlockTrezorAccount(this.state.selectedAccount) + .then(_ => { + this.props.history.push(DEFAULT_ROUTE) + }).catch(e => { + this.setState({ error: e.toString() }) + }) } + onCancel = () => { + this.props.history.push(DEFAULT_ROUTE) + } renderError () { return this.state.error @@ -67,10 +87,13 @@ class ConnectHardwareForm extends Component { return h(AccountList, { accounts: this.state.accounts, + selectedAccount: this.state.selectedAccount, onAccountChange: this.onAccountChange, network: this.props.network, getPage: this.getPage, history: this.props.history, + onUnlockAccount: this.onUnlockAccount, + onCancel: this.onCancel, }) } -- cgit From dddbb4250b30b7263eb97ddc2e23791166bcc98e Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 6 Jul 2018 20:04:20 -0400 Subject: update connect harwdware screen --- .../connect-hardware/connect-screen.js | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index ec6a11b40..cf6353bf8 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -10,9 +10,9 @@ class ConnectScreen extends Component { renderUnsupportedBrowser () { return ( h('div', {}, [ - h('div.hw-unsupported-browser', [ - h('h3.hw-unsupported-browser__title', {}, this.context.t('browserNotSupported')), - h('p.hw-unsupported-browser__msg', {}, this.context.t('chromeRequiredForTrezor')), + h('div.hw-connect', [ + h('h3.hw-connect__title', {}, this.context.t('browserNotSupported')), + h('p.hw-connect__msg', {}, this.context.t('chromeRequiredForTrezor')), ]), h( 'button.btn-primary.btn--large', @@ -25,18 +25,30 @@ class ConnectScreen extends Component { ) } - renderConnectButton () { - return h( + renderConnectScreen () { + return ( + h('div', {}, [ + h('div.hw-connect', [ + h('h3.hw-connect__title', {}, this.context.t('trezorHardwareWallet')), + h('p.hw-connect__msg', {}, this.context.t('connectToTrezorHelp')), + h('p.hw-connect__msg', {}, [ + this.context.t('connectToTrezorTrouble'), + h('a.___info-link', { url: 'https://support.metamask.io/', target: '_blank'}, this.context.t('learnMore')), + ]), + ]), + h( 'button.btn-primary.btn--large', - { onClick: this.props.connectToTrezor.bind(this), style: { margin: 12 } }, + { onClick: this.props.connectToTrezor.bind(this) }, this.props.btnText - ) + ), + ]) + ) } render () { const isChrome = window.navigator.userAgent.search('Chrome') !== -1 if (isChrome) { - return this.renderConnectButton() + return this.renderConnectScreen() } return this.renderUnsupportedBrowser() } -- cgit From 512760154528c47213cc8ff75475c21e3e674a23 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 6 Jul 2018 20:37:08 -0400 Subject: copy updated --- .../pages/create-account/connect-hardware/connect-screen.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index cf6353bf8..dd9fdfba2 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -33,7 +33,10 @@ class ConnectScreen extends Component { h('p.hw-connect__msg', {}, this.context.t('connectToTrezorHelp')), h('p.hw-connect__msg', {}, [ this.context.t('connectToTrezorTrouble'), - h('a.___info-link', { url: 'https://support.metamask.io/', target: '_blank'}, this.context.t('learnMore')), + h('a.hw-connect__link', { + href: 'https://support.metamask.io/', + target: '_blank', + }, ` ${this.context.t('learnMore')}`), ]), ]), h( -- cgit From 7cca7ace2ea4cd4b9d3a242067c9a7c344406aba Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 9 Jul 2018 17:24:52 -0400 Subject: fix all the account related bugs --- .../connect-hardware/account-list.js | 11 +------- .../pages/create-account/connect-hardware/index.js | 29 +++++++++++++++++++--- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/account-list.js b/ui/app/components/pages/create-account/connect-hardware/account-list.js index 77e0af3ac..170d8f0b3 100644 --- a/ui/app/components/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/components/pages/create-account/connect-hardware/account-list.js @@ -2,21 +2,12 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') const genAccountLink = require('../../../../../lib/account-link.js') -const { formatBalance } = require('../../../../util') class AccountList extends Component { constructor (props, context) { super(props) } - getBalance (address) { - // Get the balance - const { accounts } = this.props - const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' - const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' - return formattedBalance - } - renderAccounts () { return h('div.hw-account-list', [ h('div.hw-account-list__title_wrapper', [ @@ -44,7 +35,7 @@ class AccountList extends Component { `${a.address.slice(0, 4)}...${a.address.slice(-4)}` ), ]), - h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), + h('span.hw-account-list__item__balance', `${a.balance}`), h( 'a.hw-account-list__item__link', { diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index 22c54d28c..1aaa0be64 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -6,6 +6,7 @@ const actions = require('../../../../actions') const ConnectScreen = require('./connect-screen') const AccountList = require('./account-list') const { DEFAULT_ROUTE } = require('../../../../routes') +const { formatBalance } = require('../../../../util') class ConnectHardwareForm extends Component { constructor (props, context) { @@ -31,20 +32,42 @@ class ConnectHardwareForm extends Component { this.setState({selectedAccount: account.toString(), error: null}) } + getBalance (address) { + // Get the balance + const { accounts } = this.props + const balanceValue = accounts && accounts[address.toLowerCase()] ? accounts[address.toLowerCase()].balance : '' + const formattedBalance = balanceValue !== null ? formatBalance(balanceValue, 6) : '...' + console.log('[TREZOR]: got balance', address, accounts, balanceValue, formattedBalance) + return formattedBalance + } + getPage = (page) => { this.props .connectHardware('trezor', page) .then(accounts => { + console.log('[TREZOR]: GOT PAGE!', accounts) if (accounts.length) { - const newState = { accounts: accounts } + const newState = {} // Default to the first account if (this.state.selectedAccount === null) { const firstAccount = accounts[0] - newState.selectedAccount = firstAccount.index.toString() + newState.selectedAccount = firstAccount.index.toString() === '0' ? firstAccount.index.toString() : null + console.log('[TREZOR]: just defaulted to account', newState.selectedAccount) // If the page doesn't contain the selected account, let's deselect it - } else if (!accounts.filter(a => a.index.toString() === '').lenght) { + } else if (!accounts.filter(a => a.index.toString() === this.state.selectedAccount).length) { newState.selectedAccount = null + console.log('[TREZOR]: just removed default account', newState.selectedAccount) } + + console.log('[TREZOR]: mapping balances') + + // Map accounts with balances + newState.accounts = accounts.map(account => { + account.balance = this.getBalance(account.address) + return account + }) + + console.log('[TREZOR]: ABOUT TO RENDER ACCOUNTS: ', page, newState.accounts) this.setState(newState) } }) -- cgit From 2de3039b6b21ca05ef185c078b67815448864c72 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 9 Jul 2018 17:55:37 -0400 Subject: fix account duplication --- ui/app/components/pages/create-account/connect-hardware/index.js | 6 ------ 1 file changed, 6 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index 1aaa0be64..126102235 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -37,7 +37,6 @@ class ConnectHardwareForm extends Component { const { accounts } = this.props const balanceValue = accounts && accounts[address.toLowerCase()] ? accounts[address.toLowerCase()].balance : '' const formattedBalance = balanceValue !== null ? formatBalance(balanceValue, 6) : '...' - console.log('[TREZOR]: got balance', address, accounts, balanceValue, formattedBalance) return formattedBalance } @@ -45,21 +44,17 @@ class ConnectHardwareForm extends Component { this.props .connectHardware('trezor', page) .then(accounts => { - console.log('[TREZOR]: GOT PAGE!', accounts) if (accounts.length) { const newState = {} // Default to the first account if (this.state.selectedAccount === null) { const firstAccount = accounts[0] newState.selectedAccount = firstAccount.index.toString() === '0' ? firstAccount.index.toString() : null - console.log('[TREZOR]: just defaulted to account', newState.selectedAccount) // If the page doesn't contain the selected account, let's deselect it } else if (!accounts.filter(a => a.index.toString() === this.state.selectedAccount).length) { newState.selectedAccount = null - console.log('[TREZOR]: just removed default account', newState.selectedAccount) } - console.log('[TREZOR]: mapping balances') // Map accounts with balances newState.accounts = accounts.map(account => { @@ -67,7 +62,6 @@ class ConnectHardwareForm extends Component { return account }) - console.log('[TREZOR]: ABOUT TO RENDER ACCOUNTS: ', page, newState.accounts) this.setState(newState) } }) -- cgit From 80e875308b4447ed38d7e0f677570d73956dd9de Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 11 Jul 2018 21:21:36 -0400 Subject: forget device and autiload account features added --- .../connect-hardware/account-list.js | 10 +++++++ .../pages/create-account/connect-hardware/index.js | 31 +++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/account-list.js b/ui/app/components/pages/create-account/connect-hardware/account-list.js index 170d8f0b3..3bd6a00a7 100644 --- a/ui/app/components/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/components/pages/create-account/connect-hardware/account-list.js @@ -90,11 +90,20 @@ class AccountList extends Component { ]) } + renderForgetDevice () { + return h('div.hw-forget-device-container', {}, [ + h('a', { + onClick: this.props.onForgetDevice.bind(this), + }, this.context.t('forgetDevice')), + ]) + } + render () { return h('div', {}, [ this.renderAccounts(), this.renderPagination(), this.renderButtons(), + this.renderForgetDevice(), ]) } @@ -104,6 +113,7 @@ class AccountList extends Component { AccountList.propTypes = { accounts: PropTypes.array.isRequired, onAccountChange: PropTypes.func.isRequired, + onForgetDevice: PropTypes.func.isRequired, getPage: PropTypes.func.isRequired, network: PropTypes.string, selectedAccount: PropTypes.string, diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index 126102235..9aef36cfb 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -13,13 +13,19 @@ class ConnectHardwareForm extends Component { super(props) this.state = { error: null, - response: null, btnText: context.t('connectToTrezor'), selectedAccount: null, accounts: [], } } + async componentDidMount () { + const unlocked = await this.props.checkHardwareStatus('trezor') + if (unlocked) { + this.getPage(0) + } + } + connectToTrezor = () => { if (this.state.accounts.length) { return null @@ -70,6 +76,20 @@ class ConnectHardwareForm extends Component { }) } + onForgetDevice = () => { + this.props.forgetDevice('trezor') + .then(_ => { + this.setState({ + error: null, + btnText: this.context.t('connectToTrezor'), + selectedAccount: null, + accounts: [], + }) + }).catch(e => { + this.setState({ error: e.toString() }) + }) + } + onUnlockAccount = () => { if (this.state.selectedAccount === null) { @@ -110,6 +130,7 @@ class ConnectHardwareForm extends Component { getPage: this.getPage, history: this.props.history, onUnlockAccount: this.onUnlockAccount, + onForgetDevice: this.onForgetDevice, onCancel: this.onCancel, }) } @@ -127,6 +148,8 @@ ConnectHardwareForm.propTypes = { showImportPage: PropTypes.func, showConnectPage: PropTypes.func, connectHardware: PropTypes.func, + checkHardwareStatus: PropTypes.func, + forgetDevice: PropTypes.func, unlockTrezorAccount: PropTypes.func, numberOfExistingAccounts: PropTypes.number, history: PropTypes.object, @@ -154,6 +177,12 @@ const mapDispatchToProps = dispatch => { connectHardware: (deviceName, page) => { return dispatch(actions.connectHardware(deviceName, page)) }, + checkHardwareStatus: (deviceName) => { + return dispatch(actions.checkHardwareStatus(deviceName)) + }, + forgetDevice: (deviceName) => { + return dispatch(actions.forgetDevice(deviceName)) + }, unlockTrezorAccount: index => { return dispatch(actions.unlockTrezorAccount(index)) }, -- cgit From 289795fb1251f3d6bc2206efb2d640fcedae5ee4 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 13 Jul 2018 00:09:42 -0400 Subject: fix account balance bug --- .../pages/create-account/connect-hardware/index.js | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index 9aef36cfb..fa9cf4894 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -19,6 +19,18 @@ class ConnectHardwareForm extends Component { } } + componentWillReceiveProps (nextProps) { + const { accounts } = nextProps + const newAccounts = this.state.accounts.map(a => { + const normalizedAddress = a.address.toLowerCase() + const balanceValue = accounts[normalizedAddress] && accounts[normalizedAddress].balance || null + a.balance = balanceValue ? formatBalance(balanceValue, 6) : '...' + return a + }) + this.setState({accounts: newAccounts}) + } + + async componentDidMount () { const unlocked = await this.props.checkHardwareStatus('trezor') if (unlocked) { @@ -38,14 +50,6 @@ class ConnectHardwareForm extends Component { this.setState({selectedAccount: account.toString(), error: null}) } - getBalance (address) { - // Get the balance - const { accounts } = this.props - const balanceValue = accounts && accounts[address.toLowerCase()] ? accounts[address.toLowerCase()].balance : '' - const formattedBalance = balanceValue !== null ? formatBalance(balanceValue, 6) : '...' - return formattedBalance - } - getPage = (page) => { this.props .connectHardware('trezor', page) @@ -64,7 +68,9 @@ class ConnectHardwareForm extends Component { // Map accounts with balances newState.accounts = accounts.map(account => { - account.balance = this.getBalance(account.address) + const normalizedAddress = account.address.toLowerCase() + const balanceValue = this.props.accounts[normalizedAddress] && this.props.accounts[normalizedAddress].balance || null + account.balance = balanceValue ? formatBalance(balanceValue, 6) : '...' return account }) -- cgit From 82a93bb2872809df19744afdd95c68485c0dcd25 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 13 Jul 2018 02:03:54 -0400 Subject: detect ability to open popup instead of browser --- .../create-account/connect-hardware/connect-screen.js | 14 ++++++++------ .../pages/create-account/connect-hardware/index.js | 5 +++++ 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index dd9fdfba2..0dd8e285b 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -16,9 +16,11 @@ class ConnectScreen extends Component { ]), h( 'button.btn-primary.btn--large', - { onClick: () => global.platform.openWindow({ - url: 'https://google.com/chrome', - }), style: { margin: 12 } }, + { + onClick: () => global.platform.openWindow({ + url: 'https://google.com/chrome', + }), + }, this.context.t('downloadGoogleChrome') ), ]) @@ -49,8 +51,7 @@ class ConnectScreen extends Component { } render () { - const isChrome = window.navigator.userAgent.search('Chrome') !== -1 - if (isChrome) { + if (this.props.browserSupported) { return this.renderConnectScreen() } return this.renderUnsupportedBrowser() @@ -59,7 +60,8 @@ class ConnectScreen extends Component { ConnectScreen.propTypes = { connectToTrezor: PropTypes.func.isRequired, - btnText: PropTypes.string, + btnText: PropTypes.string.isRequired, + browserSupported: PropTypes.bool.isRequired, } ConnectScreen.contextTypes = { diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index fa9cf4894..689e88f2e 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -16,6 +16,7 @@ class ConnectHardwareForm extends Component { btnText: context.t('connectToTrezor'), selectedAccount: null, accounts: [], + browserSupported: true, } } @@ -78,6 +79,9 @@ class ConnectHardwareForm extends Component { } }) .catch(e => { + if (e === 'Window blocked') { + this.setState({ browserSupported: false }) + } this.setState({ btnText: this.context.t('connectToTrezor') }) }) } @@ -125,6 +129,7 @@ class ConnectHardwareForm extends Component { return h(ConnectScreen, { connectToTrezor: this.connectToTrezor, btnText: this.state.btnText, + browserSupported: this.state.browserSupported, }) } -- cgit From 53995463883c062157a3d725e7cb8fe54486badb Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 13 Jul 2018 13:49:20 -0400 Subject: added affiliate link to trezor --- .../pages/create-account/connect-hardware/connect-screen.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 0dd8e285b..8d9980b10 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -46,6 +46,12 @@ class ConnectScreen extends Component { { onClick: this.props.connectToTrezor.bind(this) }, this.props.btnText ), + h('div.hw-connect__get-trezor', {}, [ + h('a', { + href: 'https://shop.trezor.io/?a=metamask', + target: '_blank', + }, this.context.t('getYourTrezor')), + ]), ]) ) } -- cgit From 55382e9842c4f4136c88e441298193cc7abd8ba9 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 13 Jul 2018 15:19:21 -0400 Subject: fix account selection --- ui/app/components/pages/create-account/connect-hardware/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index 689e88f2e..dc9907f31 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -59,8 +59,11 @@ class ConnectHardwareForm extends Component { const newState = {} // Default to the first account if (this.state.selectedAccount === null) { - const firstAccount = accounts[0] - newState.selectedAccount = firstAccount.index.toString() === '0' ? firstAccount.index.toString() : null + accounts.forEach((a, i) => { + if (a.address.toLowerCase() === this.props.address) { + newState.selectedAccount = a.index.toString() + } + }) // If the page doesn't contain the selected account, let's deselect it } else if (!accounts.filter(a => a.index.toString() === this.state.selectedAccount).length) { newState.selectedAccount = null @@ -167,6 +170,7 @@ ConnectHardwareForm.propTypes = { t: PropTypes.func, network: PropTypes.string, accounts: PropTypes.object, + address: PropTypes.string, } const mapStateToProps = state => { -- cgit From cb97517b26a7732cbb7c4a9f30f85b5fa596e608 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 17 Jul 2018 18:53:37 -0400 Subject: updated account list based on new designs --- .../connect-hardware/account-list.js | 38 +++++++++++++++------- .../connect-hardware/connect-screen.js | 2 +- .../pages/create-account/connect-hardware/index.js | 2 +- 3 files changed, 28 insertions(+), 14 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/account-list.js b/ui/app/components/pages/create-account/connect-hardware/account-list.js index 3bd6a00a7..06102e16f 100644 --- a/ui/app/components/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/components/pages/create-account/connect-hardware/account-list.js @@ -8,16 +8,20 @@ class AccountList extends Component { super(props) } + renderHeader () { + return ( + h('div.hw-connect', [ + h('h3.hw-connect__title', {}, this.context.t('selectAnAccount')), + h('p.hw-connect__msg', {}, this.context.t('selectAnAccountHelp')), + ]) + ) + } + renderAccounts () { return h('div.hw-account-list', [ - h('div.hw-account-list__title_wrapper', [ - h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), - h('div.hw-account-list__device', {}, ['Trezor - ETH']), - ]), this.props.accounts.map((a, i) => { return h('div.hw-account-list__item', { key: a.address }, [ - h('span.hw-account-list__item__index', a.index + 1), h('div.hw-account-list__item__radio', [ h('input', { type: 'radio', @@ -32,10 +36,12 @@ class AccountList extends Component { { htmlFor: `address-${i}`, }, - `${a.address.slice(0, 4)}...${a.address.slice(-4)}` - ), + [ + h('span.hw-account-list__item__index', a.index + 1), + `${a.address.slice(0, 4)}...${a.address.slice(-4)}`, + h('span.hw-account-list__item__balance', `${a.balance}`), + ]), ]), - h('span.hw-account-list__item__balance', `${a.balance}`), h( 'a.hw-account-list__item__link', { @@ -71,9 +77,15 @@ class AccountList extends Component { } renderButtons () { - return h('div.new-account-create-form__buttons', {}, [ + const disabled = this.props.selectedAccount === null + const buttonProps = {} + if (disabled) { + buttonProps.disabled = true + } + + return h('div.new-account-connect-form__buttons', {}, [ h( - 'button.btn-default.btn--large.new-account-create-form__button', + 'button.btn-default.btn--large.new-account-connect-form__button', { onClick: this.props.onCancel.bind(this), }, @@ -81,9 +93,10 @@ class AccountList extends Component { ), h( - `button.btn-primary.btn--large.new-account-create-form__button ${this.props.selectedAccount === null ? '.btn-primary--disabled' : ''}`, + `button.btn-primary.btn--large.new-account-connect-form__button ${disabled ? '.btn-primary--disabled' : ''}`, { onClick: this.props.onUnlockAccount.bind(this), + ...buttonProps, }, [this.context.t('unlock')] ), @@ -99,7 +112,8 @@ class AccountList extends Component { } render () { - return h('div', {}, [ + return h('div.new-account-connect-form', {}, [ + this.renderHeader(), this.renderAccounts(), this.renderPagination(), this.renderButtons(), diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 8d9980b10..7fb36b511 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -29,7 +29,7 @@ class ConnectScreen extends Component { renderConnectScreen () { return ( - h('div', {}, [ + h('div.new-account-connect-form', {}, [ h('div.hw-connect', [ h('h3.hw-connect__title', {}, this.context.t('trezorHardwareWallet')), h('p.hw-connect__msg', {}, this.context.t('connectToTrezorHelp')), diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index dc9907f31..da42ddead 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -150,7 +150,7 @@ class ConnectHardwareForm extends Component { } render () { - return h('div.new-account-create-form', [ + return h('div', [ this.renderError(), this.renderContent(), ]) -- cgit From cbb14f1d5e50c10865838a98452ecfb4b6cb8d6a Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 17 Jul 2018 21:57:19 -0400 Subject: fix browser not supported screen --- .../components/pages/create-account/connect-hardware/connect-screen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 7fb36b511..d4c479a58 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -9,7 +9,7 @@ class ConnectScreen extends Component { renderUnsupportedBrowser () { return ( - h('div', {}, [ + h('div.new-account-connect-form', {}, [ h('div.hw-connect', [ h('h3.hw-connect__title', {}, this.context.t('browserNotSupported')), h('p.hw-connect__msg', {}, this.context.t('chromeRequiredForTrezor')), -- cgit From 49d1bdea8a47139cc814d3c49aa97bf2d542d3d5 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 18 Jul 2018 22:57:47 -0400 Subject: design done --- .../connect-hardware/connect-screen.js | 109 ++++++++++++++++----- 1 file changed, 86 insertions(+), 23 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index d4c479a58..47288c73f 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -27,34 +27,97 @@ class ConnectScreen extends Component { ) } + renderHeader () { + return ( + h('div.hw-connect__header', {}, [ + h('h3.hw-connect__header__title', {}, this.context.t(`hardwareSupport`)), + h('p.hw-connect__header__msg', {}, this.context.t(`hardwareSupportMsg`)), + ]) + ) + } + + renderTrezorAffiliateLink () { + return h('div.hw-connect__get-trezor', {}, [ + h('p.hw-connect__get-trezor__msg', {}, this.context.t(`dontHaveATrezorWallet`)), + h('a.hw-connect__get-trezor__link', { + href: 'https://shop.trezor.io/?a=metamask', + target: '_blank', + }, this.context.t('orderOneHere')), + ]) + } + + renderConnectToTrezorButton () { + return h( + 'button.btn-primary.btn--large', + { onClick: this.props.connectToTrezor.bind(this) }, + this.props.btnText + ) + } + + renderLearnMore () { + return ( + h('p.hw-connect__learn-more', {}, [ + this.context.t('learnMore'), + h('img.hw-connect__learn-more__arrow', { src: 'images/caret-right.svg'}), + ]) + ) + } + + renderTutorialSteps () { + const steps = [ + { + asset: 'hardware-wallet-step-1', + dimensions: {width: '225px', height: '75px'}, + }, + { + asset: 'hardware-wallet-step-2', + dimensions: {width: '300px', height: '100px'}, + }, + { + asset: 'hardware-wallet-step-3', + dimensions: {width: '120px', height: '90px'}, + }, + ] + + return h('.hw-tutorial', {}, + steps.map((step, i) => ( + h('div.hw-connect', [ + h('h3.hw-connect__title', {}, this.context.t(`step${i + 1}HardwareWallet`)), + h('p.hw-connect__msg', {}, this.context.t(`step${i + 1}HardwareWalletMsg`)), + h('img.hw-connect__step-asset', { src: `images/${step.asset}.svg`, ...step.dimensions }), + ]) + )) + ) + } + + renderFooter () { + return ( + h('div.hw-connect__footer', {}, [ + h('h3.hw-connect__footer__title', {}, this.context.t(`readyToConnect`)), + this.renderConnectToTrezorButton(), + h('p.hw-connect__footer__msg', {}, [ + this.context.t(`havingTroubleConnecting`), + h('a.hw-connect__footer__link', { + href: '#', + target: '_blank', + }, this.context.t('getHelp')), + ]), + ]) + ) + } + renderConnectScreen () { return ( h('div.new-account-connect-form', {}, [ - h('div.hw-connect', [ - h('h3.hw-connect__title', {}, this.context.t('trezorHardwareWallet')), - h('p.hw-connect__msg', {}, this.context.t('connectToTrezorHelp')), - h('p.hw-connect__msg', {}, [ - this.context.t('connectToTrezorTrouble'), - h('a.hw-connect__link', { - href: 'https://support.metamask.io/', - target: '_blank', - }, ` ${this.context.t('learnMore')}`), - ]), - ]), - h( - 'button.btn-primary.btn--large', - { onClick: this.props.connectToTrezor.bind(this) }, - this.props.btnText - ), - h('div.hw-connect__get-trezor', {}, [ - h('a', { - href: 'https://shop.trezor.io/?a=metamask', - target: '_blank', - }, this.context.t('getYourTrezor')), - ]), + this.renderHeader(), + this.renderTrezorAffiliateLink(), + this.renderConnectToTrezorButton(), + this.renderLearnMore(), + this.renderTutorialSteps(), + this.renderFooter(), ]) ) - } + } render () { if (this.props.browserSupported) { -- cgit From 2bfddc288e64f130d1677afca4448202181523ea Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 18 Jul 2018 23:12:49 -0400 Subject: scroll smooth --- .../create-account/connect-hardware/connect-screen.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 47288c73f..5c6c54acf 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -54,9 +54,15 @@ class ConnectScreen extends Component { ) } + scrollToTutorial = (e) => { + if (this.referenceNode) this.referenceNode.scrollIntoView({behavior: 'smooth'}) + } + renderLearnMore () { return ( - h('p.hw-connect__learn-more', {}, [ + h('p.hw-connect__learn-more', { + onClick: this.scrollToTutorial, + }, [ this.context.t('learnMore'), h('img.hw-connect__learn-more__arrow', { src: 'images/caret-right.svg'}), ]) @@ -79,9 +85,11 @@ class ConnectScreen extends Component { }, ] - return h('.hw-tutorial', {}, + return h('.hw-tutorial', { + ref: node => { this.referenceNode = node }, + }, steps.map((step, i) => ( - h('div.hw-connect', [ + h('div.hw-connect', {}, [ h('h3.hw-connect__title', {}, this.context.t(`step${i + 1}HardwareWallet`)), h('p.hw-connect__msg', {}, this.context.t(`step${i + 1}HardwareWalletMsg`)), h('img.hw-connect__step-asset', { src: `images/${step.asset}.svg`, ...step.dimensions }), -- cgit From 086ab6e1e1aa715b7a7918d10b8c1afcaeda38c7 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 18 Jul 2018 23:57:09 -0400 Subject: lint --- .../components/pages/create-account/connect-hardware/connect-screen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 5c6c54acf..55d2eadce 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -85,7 +85,7 @@ class ConnectScreen extends Component { }, ] - return h('.hw-tutorial', { + return h('.hw-tutorial', { ref: node => { this.referenceNode = node }, }, steps.map((step, i) => ( -- cgit From a6e0eef8f4280041380a7c462069b2c205999130 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 19 Jul 2018 00:14:13 -0400 Subject: fix unsupported browser view --- .../components/pages/create-account/connect-hardware/connect-screen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index 55d2eadce..bf4cf08f9 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -9,7 +9,7 @@ class ConnectScreen extends Component { renderUnsupportedBrowser () { return ( - h('div.new-account-connect-form', {}, [ + h('div.new-account-connect-form.unsupported-browser', {}, [ h('div.hw-connect', [ h('h3.hw-connect__title', {}, this.context.t('browserNotSupported')), h('p.hw-connect__msg', {}, this.context.t('chromeRequiredForTrezor')), -- cgit From 514148ffa1652b4e23ffe04fbe23bb0eadbdecb7 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 19 Jul 2018 00:16:10 -0400 Subject: fix support link --- .../components/pages/create-account/connect-hardware/connect-screen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js index bf4cf08f9..cb2b86595 100644 --- a/ui/app/components/pages/create-account/connect-hardware/connect-screen.js +++ b/ui/app/components/pages/create-account/connect-hardware/connect-screen.js @@ -106,7 +106,7 @@ class ConnectScreen extends Component { h('p.hw-connect__footer__msg', {}, [ this.context.t(`havingTroubleConnecting`), h('a.hw-connect__footer__link', { - href: '#', + href: 'https://support.metamask.io/', target: '_blank', }, this.context.t('getHelp')), ]), -- cgit From df19163bf9611d75aaf8ea6da52651dbba9a5e00 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Thu, 19 Jul 2018 02:31:13 -0400 Subject: last css fixes --- .../create-account/connect-hardware/account-list.js | 8 ++++---- .../pages/create-account/connect-hardware/index.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/account-list.js b/ui/app/components/pages/create-account/connect-hardware/account-list.js index 06102e16f..c722d1f55 100644 --- a/ui/app/components/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/components/pages/create-account/connect-hardware/account-list.js @@ -59,7 +59,7 @@ class AccountList extends Component { renderPagination () { return h('div.hw-list-pagination', [ h( - 'button.btn-primary.hw-list-pagination__button', + 'button.hw-list-pagination__button', { onClick: () => this.props.getPage(-1), }, @@ -67,7 +67,7 @@ class AccountList extends Component { ), h( - 'button.btn-primary.hw-list-pagination__button', + 'button.hw-list-pagination__button', { onClick: () => this.props.getPage(1), }, @@ -93,7 +93,7 @@ class AccountList extends Component { ), h( - `button.btn-primary.btn--large.new-account-connect-form__button ${disabled ? '.btn-primary--disabled' : ''}`, + `button.btn-primary.btn--large.new-account-connect-form__button.unlock ${disabled ? '.btn-primary--disabled' : ''}`, { onClick: this.props.onUnlockAccount.bind(this), ...buttonProps, @@ -112,7 +112,7 @@ class AccountList extends Component { } render () { - return h('div.new-account-connect-form', {}, [ + return h('div.new-account-connect-form.account-list', {}, [ this.renderHeader(), this.renderAccounts(), this.renderPagination(), diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index da42ddead..cc3761c04 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -51,11 +51,26 @@ class ConnectHardwareForm extends Component { this.setState({selectedAccount: account.toString(), error: null}) } + showTemporaryAlert () { + this.props.showAlert(this.context.t('hardwareWalletConnected')) + // Autohide the alert after 5 seconds + setTimeout(_ => { + this.props.hideAlert() + }, 5000) + } + getPage = (page) => { this.props .connectHardware('trezor', page) .then(accounts => { if (accounts.length) { + + // If we just loaded the accounts for the first time + // show the global alert + if (this.state.accounts.length === 0) { + this.showTemporaryAlert() + } + const newState = {} // Default to the first account if (this.state.selectedAccount === null) { @@ -164,6 +179,8 @@ ConnectHardwareForm.propTypes = { connectHardware: PropTypes.func, checkHardwareStatus: PropTypes.func, forgetDevice: PropTypes.func, + showAlert: PropTypes.func, + hideAlert: PropTypes.func, unlockTrezorAccount: PropTypes.func, numberOfExistingAccounts: PropTypes.number, history: PropTypes.object, @@ -203,6 +220,8 @@ const mapDispatchToProps = dispatch => { }, showImportPage: () => dispatch(actions.showImportPage()), showConnectPage: () => dispatch(actions.showConnectPage()), + showAlert: (msg) => dispatch(actions.showAlert(msg)), + hideAlert: () => dispatch(actions.hideAlert()), } } -- cgit From bcbe7fef2e30d97465fb3f94d92293e1ea11e56f Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 23 Jul 2018 01:18:39 -0400 Subject: show alert ONLY when device is connected --- .../pages/create-account/connect-hardware/index.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'ui/app/components/pages/create-account') diff --git a/ui/app/components/pages/create-account/connect-hardware/index.js b/ui/app/components/pages/create-account/connect-hardware/index.js index cc3761c04..3f66e7098 100644 --- a/ui/app/components/pages/create-account/connect-hardware/index.js +++ b/ui/app/components/pages/create-account/connect-hardware/index.js @@ -17,6 +17,7 @@ class ConnectHardwareForm extends Component { selectedAccount: null, accounts: [], browserSupported: true, + unlocked: false, } } @@ -32,9 +33,14 @@ class ConnectHardwareForm extends Component { } - async componentDidMount () { + componentDidMount () { + this.checkIfUnlocked() + } + + async checkIfUnlocked () { const unlocked = await this.props.checkHardwareStatus('trezor') if (unlocked) { + this.setState({unlocked: true}) this.getPage(0) } } @@ -66,12 +72,12 @@ class ConnectHardwareForm extends Component { if (accounts.length) { // If we just loaded the accounts for the first time - // show the global alert - if (this.state.accounts.length === 0) { + // (device previously locked) show the global alert + if (this.state.accounts.length === 0 && !this.state.unlocked) { this.showTemporaryAlert() } - const newState = {} + const newState = { unlocked: true } // Default to the first account if (this.state.selectedAccount === null) { accounts.forEach((a, i) => { @@ -112,6 +118,7 @@ class ConnectHardwareForm extends Component { btnText: this.context.t('connectToTrezor'), selectedAccount: null, accounts: [], + unlocked: false, }) }).catch(e => { this.setState({ error: e.toString() }) -- cgit