From 1bbe0ed9e8fb9f9944c27453cb9791686c4d8d9d Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 12:00:56 -0700 Subject: Scaffold new account view --- ui/app/accounts/index.js | 2 +- ui/app/accounts/new.js | 60 ++++++++++++++++++++++++++++++++++++++++++++ ui/app/actions.js | 8 ++++++ ui/app/app.js | 4 +++ ui/app/components/tab-bar.js | 35 ++++++++++++++++++++++++++ ui/app/css/lib.css | 8 ++++++ ui/app/reducers/app.js | 9 +++++++ 7 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 ui/app/accounts/new.js create mode 100644 ui/app/components/tab-bar.js (limited to 'ui/app') diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js index 2e8321a77..65cf82b2c 100644 --- a/ui/app/accounts/index.js +++ b/ui/app/accounts/index.js @@ -143,7 +143,7 @@ AccountsScreen.prototype.onShowDetail = function (address, event) { } AccountsScreen.prototype.addNewAccount = function () { - this.props.dispatch(actions.addNewAccount(0)) + this.props.dispatch(actions.navigateToNewAccountScreen()) } AccountsScreen.prototype.goHome = function () { diff --git a/ui/app/accounts/new.js b/ui/app/accounts/new.js new file mode 100644 index 000000000..0356bb313 --- /dev/null +++ b/ui/app/accounts/new.js @@ -0,0 +1,60 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect +const TabBar = require('../components/tab-bar') + +module.exports = connect(mapStateToProps)(NewAccountScreen) + +function mapStateToProps (state) { + return {} +} + +inherits(NewAccountScreen, Component) +function NewAccountScreen () { + Component.call(this) +} + +NewAccountScreen.prototype.render = function () { + const props = this.props + const state = this.state || {} + const subview = state.subview || 'new' + + return ( + h('.flex-column', { + style: { + }, + }, [ + + // title and nav + h('.flex-row.space-between', { + style: { + alignItems: 'center', + padding: '0px 20px', + } + }, [ + h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { + onClick: this.goHome.bind(this), + }), + h('h2.page-subtitle', 'Add Account'), + h('i', { style: { width: '18px' } }), + ]), + + h(TabBar, { + tabs: [ + { content: 'Create New', key: 'new' }, + { content: 'Import', key: 'import' }, + ], + defaultTab: 'new', + tabSelected: (key) => { + console.log('selected ' + key) + } + }), + + ]) + ) +} + +NewAccountScreen.prototype.goHome = function() { + this.props.dispatch(actions.showAccountPage()) +} diff --git a/ui/app/actions.js b/ui/app/actions.js index 070ba2da0..0a0a24725 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -28,6 +28,8 @@ var actions = { createNewVaultInProgress: createNewVaultInProgress, addNewKeyring, addNewAccount, + NEW_ACCOUNT_SCREEN: 'NEW_ACCOUNT_SCREEN', + navigateToNewAccountScreen, showNewVaultSeed: showNewVaultSeed, showInfoPage: showInfoPage, // seed recovery actions @@ -250,6 +252,12 @@ function addNewKeyring (type, opts) { } } +function navigateToNewAccountScreen() { + return { + type: this.NEW_ACCOUNT_SCREEN + } +} + function addNewAccount (ringNumber = 0) { return (dispatch) => { dispatch(actions.showLoadingIndication()) diff --git a/ui/app/app.js b/ui/app/app.js index a2532c153..1651442e9 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -29,6 +29,7 @@ const QrView = require('./components/qr-code') const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete') const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation') +const NewAccountScreen = require('./accounts/new') module.exports = connect(mapStateToProps)(App) @@ -400,6 +401,9 @@ App.prototype.renderPrimary = function () { case 'accountDetail': return h(AccountDetailScreen, {key: 'account-detail'}) + case 'new-account': + return h(NewAccountScreen, {key: 'new-account'}) + case 'sendTransaction': return h(SendTransactionScreen, {key: 'send-transaction'}) diff --git a/ui/app/components/tab-bar.js b/ui/app/components/tab-bar.js new file mode 100644 index 000000000..65078e0a4 --- /dev/null +++ b/ui/app/components/tab-bar.js @@ -0,0 +1,35 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits + +module.exports = TabBar + +inherits(TabBar, Component) +function TabBar () { + Component.call(this) +} + +TabBar.prototype.render = function () { + const props = this.props + const state = this.state || {} + const { tabs = [], defaultTab, tabSelected } = props + const { subview = defaultTab } = state + + return ( + h('.flex-row.space-around.text-transform-uppercase', { + style: { + background: '#EBEBEB', + color: '#AEAEAE', + paddingTop: '4px', + }, + }, tabs.map((tab) => { + const { key, content } = tab + return h(subview === key ? '.activeForm' : '.inactiveForm.pointer', { + onClick: () => { + this.setState({ subview: key }) + tabSelected(key) + }, + }, content) + })) + ) +} diff --git a/ui/app/css/lib.css b/ui/app/css/lib.css index bcd6a4a67..95764c2b8 100644 --- a/ui/app/css/lib.css +++ b/ui/app/css/lib.css @@ -23,6 +23,14 @@ flex-direction: column; } +.space-between { + justify-content: space-between; +} + +.space-around { + justify-content: space-around; +} + .flex-column-bottom { display: flex; flex-direction: column-reverse; diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 49507eb30..7f4537510 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -106,6 +106,15 @@ function reduceApp (state, action) { isLoading: false, }) + case actions.NEW_ACCOUNT_SCREEN: + return extend(appState, { + currentView: { + name: 'new-account', + context: appState.currentView.context, + }, + transForward: true, + }) + case actions.SHOW_SEND_PAGE: return extend(appState, { currentView: { -- cgit v1.2.3 From 1af0d609bd5ac2a06b8f0b92cd78c224b136889e Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 12:02:00 -0700 Subject: Convert buy subview to new tab bar component --- ui/app/components/buy-button-subview.js | 83 +++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 36 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js index b564733b1..4e2d3739c 100644 --- a/ui/app/components/buy-button-subview.js +++ b/ui/app/components/buy-button-subview.js @@ -7,6 +7,7 @@ const CoinbaseForm = require('./coinbase-form') const ShapeshiftForm = require('./shapeshift-form') const extension = require('../../../app/scripts/lib/extension') const Loading = require('./loading') +const TabBar = require('./tab-bar') module.exports = connect(mapStateToProps)(BuyButtonSubview) @@ -53,43 +54,53 @@ BuyButtonSubview.prototype.render = function () { h(Loading, { isLoading }), - h('h3.flex-row.text-transform-uppercase', { - style: { - background: '#EBEBEB', - color: '#AEAEAE', - paddingTop: '4px', - justifyContent: 'space-around', - }, - }, [ - h(currentForm.coinbase ? '.activeForm' : '.inactiveForm.pointer', { - onClick: () => props.dispatch(actions.coinBaseSubview()), - }, 'Coinbase'), - h('a', { - onClick: (event) => this.navigateTo('https://github.com/MetaMask/faq/blob/master/COINBASE.md'), - }, [ - h('i.fa.fa-question-circle', { - style: { - position: 'relative', - right: '33px', - }, - }), - ]), - h(currentForm.shapeshift ? '.activeForm' : '.inactiveForm.pointer', { - onClick: () => props.dispatch(actions.shapeShiftSubview(props.provider.type)), - }, 'Shapeshift'), + h(TabBar, { + tabs: [ + { + content: [ + 'Coinbase', + h('a', { + onClick: (event) => this.navigateTo('https://github.com/MetaMask/faq/blob/master/COINBASE.md'), + }, [ + h('i.fa.fa-question-circle', { + style: { + margin: '0px 5px', + }, + }), + ]), + ], + key: 'coinbase' + }, + { + content: [ + 'Shapeshift', + h('a', { + href: 'https://github.com/MetaMask/faq/blob/master/COINBASE.md', + onClick: (event) => this.navigateTo('https://info.shapeshift.io/about'), + }, [ + h('i.fa.fa-question-circle', { + style: { + margin: '0px 5px', + }, + }), + ]) + ], + key: 'shapeshift' + }, + ], + defaultTab: 'coinbase', + tabSelected: (key) => { + switch (key) { + case 'coinbase': + props.dispatch(actions.coinBaseSubview()) + break + case 'shapeshift': + props.dispatch(actions.shapeShiftSubview(props.provider.type)) + break + } + } + }), - h('a', { - href: 'https://github.com/MetaMask/faq/blob/master/COINBASE.md', - onClick: (event) => this.navigateTo('https://info.shapeshift.io/about'), - }, [ - h('i.fa.fa-question-circle', { - style: { - position: 'relative', - right: '28px', - }, - }), - ]), - ]), this.formVersionSubview(), ]) ) -- cgit v1.2.3 From 2cf2ceae2127f5a088f5bc36b1a763c85f7a44cd Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 12:02:20 -0700 Subject: Remove unused class --- ui/app/unlock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app') diff --git a/ui/app/unlock.js b/ui/app/unlock.js index ec467f483..b2c693493 100644 --- a/ui/app/unlock.js +++ b/ui/app/unlock.js @@ -26,7 +26,7 @@ UnlockScreen.prototype.render = function () { const state = this.props const warning = state.warning return ( - h('.flex-column.hey-im-here', [ + h('.flex-column', [ h('.unlock-screen.flex-column.flex-center.flex-grow', [ h(Mascot, { -- cgit v1.2.3 From 19f7041ba42a5ad806ace8286c6e0675b94ca69a Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 12:27:26 -0700 Subject: Add account adding subview placeholders --- ui/app/accounts/add.js | 82 +++++++++++++++++++++++++++++++++++++++++++++++ ui/app/accounts/import.js | 30 +++++++++++++++++ ui/app/accounts/new.js | 44 ++++--------------------- ui/app/app.js | 4 +-- 4 files changed, 121 insertions(+), 39 deletions(-) create mode 100644 ui/app/accounts/add.js create mode 100644 ui/app/accounts/import.js (limited to 'ui/app') diff --git a/ui/app/accounts/add.js b/ui/app/accounts/add.js new file mode 100644 index 000000000..a750531f7 --- /dev/null +++ b/ui/app/accounts/add.js @@ -0,0 +1,82 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect +const actions = require('../../actions') + +// Components +const TabBar = require('../components/tab-bar') + +// Subviews +const NewAccountView = require('./new') +const ImportAccountView = require('./import') + +module.exports = connect(mapStateToProps)(AddAccountScreen) + +function mapStateToProps (state) { + return {} +} + +inherits(AddAccountScreen, Component) +function AddAccountScreen () { + Component.call(this) +} + +AddAccountScreen.prototype.render = function () { + const props = this.props + const state = this.state || {} + const subview = state.subview || 'new' + + return ( + h('.flex-column', { + style: { + }, + }, [ + + // title and nav + h('.flex-row.space-between', { + style: { + alignItems: 'center', + padding: '0px 20px', + } + }, [ + h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { + onClick: this.goHome.bind(this), + }), + h('h2.page-subtitle', 'Add Account'), + h('i', { style: { width: '18px' } }), + ]), + + h(TabBar, { + tabs: [ + { content: 'Create New', key: 'new' }, + { content: 'Import', key: 'import' }, + ], + defaultTab: 'new', + tabSelected: (key) => { + this.setState({ subview: key }) + } + }), + + this.renderNewOrImport(), + + ]) + ) +} + +AddAccountScreen.prototype.goHome = function() { + this.props.dispatch(actions.showAccountPage()) +} + +AddAccountScreen.prototype.renderNewOrImport = function() { + const state = this.state || {} + const subview = state.subview || 'new' + + switch (subview) { + case 'new': + return h(NewAccountView) + + case 'import': + return h(ImportAccountView) + } +} diff --git a/ui/app/accounts/import.js b/ui/app/accounts/import.js new file mode 100644 index 000000000..d15b30fd2 --- /dev/null +++ b/ui/app/accounts/import.js @@ -0,0 +1,30 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect + +module.exports = connect(mapStateToProps)(COMPONENTNAME) + +function mapStateToProps (state) { + return {} +} + +inherits(COMPONENTNAME, Component) +function COMPONENTNAME () { + Component.call(this) +} + +COMPONENTNAME.prototype.render = function () { + const props = this.props + + return ( + h('div', { + style: { + background: 'blue', + }, + }, [ + `Hello, ${props.sender}`, + ]) + ) +} + diff --git a/ui/app/accounts/new.js b/ui/app/accounts/new.js index 0356bb313..07fc1e672 100644 --- a/ui/app/accounts/new.js +++ b/ui/app/accounts/new.js @@ -2,59 +2,29 @@ const inherits = require('util').inherits const Component = require('react').Component const h = require('react-hyperscript') const connect = require('react-redux').connect -const TabBar = require('../components/tab-bar') -module.exports = connect(mapStateToProps)(NewAccountScreen) +module.exports = connect(mapStateToProps)(COMPONENTNAME) function mapStateToProps (state) { return {} } -inherits(NewAccountScreen, Component) -function NewAccountScreen () { +inherits(COMPONENTNAME, Component) +function COMPONENTNAME () { Component.call(this) } -NewAccountScreen.prototype.render = function () { +COMPONENTNAME.prototype.render = function () { const props = this.props - const state = this.state || {} - const subview = state.subview || 'new' return ( - h('.flex-column', { + h('div', { style: { + background: 'red', }, }, [ - - // title and nav - h('.flex-row.space-between', { - style: { - alignItems: 'center', - padding: '0px 20px', - } - }, [ - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: this.goHome.bind(this), - }), - h('h2.page-subtitle', 'Add Account'), - h('i', { style: { width: '18px' } }), - ]), - - h(TabBar, { - tabs: [ - { content: 'Create New', key: 'new' }, - { content: 'Import', key: 'import' }, - ], - defaultTab: 'new', - tabSelected: (key) => { - console.log('selected ' + key) - } - }), - + `Hello, ${props.sender}`, ]) ) } -NewAccountScreen.prototype.goHome = function() { - this.props.dispatch(actions.showAccountPage()) -} diff --git a/ui/app/app.js b/ui/app/app.js index 1651442e9..ad56df8db 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -29,7 +29,7 @@ const QrView = require('./components/qr-code') const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete') const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation') -const NewAccountScreen = require('./accounts/new') +const AddAccountScreen = require('./accounts/add') module.exports = connect(mapStateToProps)(App) @@ -402,7 +402,7 @@ App.prototype.renderPrimary = function () { return h(AccountDetailScreen, {key: 'account-detail'}) case 'new-account': - return h(NewAccountScreen, {key: 'new-account'}) + return h(AddAccountScreen, {key: 'new-account'}) case 'sendTransaction': return h(SendTransactionScreen, {key: 'send-transaction'}) -- cgit v1.2.3 From bc623bbe345a9528f9fe19af2e2440540d8e70a7 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 12:31:03 -0700 Subject: Linted --- ui/app/accounts/add.js | 9 +++------ ui/app/actions.js | 2 +- ui/app/components/buy-button-subview.js | 9 ++++----- 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'ui/app') diff --git a/ui/app/accounts/add.js b/ui/app/accounts/add.js index a750531f7..9493a4e05 100644 --- a/ui/app/accounts/add.js +++ b/ui/app/accounts/add.js @@ -2,7 +2,7 @@ const inherits = require('util').inherits const Component = require('react').Component const h = require('react-hyperscript') const connect = require('react-redux').connect -const actions = require('../../actions') +const actions = require('../actions') // Components const TabBar = require('../components/tab-bar') @@ -23,9 +23,6 @@ function AddAccountScreen () { } AddAccountScreen.prototype.render = function () { - const props = this.props - const state = this.state || {} - const subview = state.subview || 'new' return ( h('.flex-column', { @@ -38,7 +35,7 @@ AddAccountScreen.prototype.render = function () { style: { alignItems: 'center', padding: '0px 20px', - } + }, }, [ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { onClick: this.goHome.bind(this), @@ -55,7 +52,7 @@ AddAccountScreen.prototype.render = function () { defaultTab: 'new', tabSelected: (key) => { this.setState({ subview: key }) - } + }, }), this.renderNewOrImport(), diff --git a/ui/app/actions.js b/ui/app/actions.js index 0a0a24725..f5456e0d2 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -254,7 +254,7 @@ function addNewKeyring (type, opts) { function navigateToNewAccountScreen() { return { - type: this.NEW_ACCOUNT_SCREEN + type: this.NEW_ACCOUNT_SCREEN, } } diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js index 4e2d3739c..4678168bb 100644 --- a/ui/app/components/buy-button-subview.js +++ b/ui/app/components/buy-button-subview.js @@ -30,7 +30,6 @@ function BuyButtonSubview () { BuyButtonSubview.prototype.render = function () { const props = this.props - const currentForm = props.buyView.formView const isLoading = props.isSubLoading return ( @@ -69,7 +68,7 @@ BuyButtonSubview.prototype.render = function () { }), ]), ], - key: 'coinbase' + key: 'coinbase', }, { content: [ @@ -83,9 +82,9 @@ BuyButtonSubview.prototype.render = function () { margin: '0px 5px', }, }), - ]) + ]), ], - key: 'shapeshift' + key: 'shapeshift', }, ], defaultTab: 'coinbase', @@ -98,7 +97,7 @@ BuyButtonSubview.prototype.render = function () { props.dispatch(actions.shapeShiftSubview(props.provider.type)) break } - } + }, }), this.formVersionSubview(), -- cgit v1.2.3 From a7af47db928590af8100f16e9e9d36ae98623357 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 14:39:53 -0700 Subject: Add import account placeholder template --- ui/app/accounts/import.js | 30 ------------------ ui/app/accounts/import/index.js | 70 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 30 deletions(-) delete mode 100644 ui/app/accounts/import.js create mode 100644 ui/app/accounts/import/index.js (limited to 'ui/app') diff --git a/ui/app/accounts/import.js b/ui/app/accounts/import.js deleted file mode 100644 index d15b30fd2..000000000 --- a/ui/app/accounts/import.js +++ /dev/null @@ -1,30 +0,0 @@ -const inherits = require('util').inherits -const Component = require('react').Component -const h = require('react-hyperscript') -const connect = require('react-redux').connect - -module.exports = connect(mapStateToProps)(COMPONENTNAME) - -function mapStateToProps (state) { - return {} -} - -inherits(COMPONENTNAME, Component) -function COMPONENTNAME () { - Component.call(this) -} - -COMPONENTNAME.prototype.render = function () { - const props = this.props - - return ( - h('div', { - style: { - background: 'blue', - }, - }, [ - `Hello, ${props.sender}`, - ]) - ) -} - diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js new file mode 100644 index 000000000..a16b1c39d --- /dev/null +++ b/ui/app/accounts/import/index.js @@ -0,0 +1,70 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect +import Select from 'react-select' + +module.exports = connect(mapStateToProps)(AccountImportSubview) + +function mapStateToProps (state) { + return { + types: state.metamask.keyringTypes, + } +} + +inherits(AccountImportSubview, Component) +function AccountImportSubview () { + Component.call(this) +} + +AccountImportSubview.prototype.render = function () { + const props = this.props + const state = this.state || {} + const { types } = props + const { type } = state + + return ( + h('div', { + style: { + }, + }, [ + h('div', { + style: { + padding: '10px', + background: 'rgb(242,242,242)', + color: 'rgb(174, 174, 174)', + }, + }, [ + h('h3', 'SELECT TYPE'), + ]), + + h('style', ` + .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label { + color: rgb(174,174,174); + } + `), + + h('div', { + style: { + padding: '10px', + }, + }, [ + h(Select, { + name: 'import-type-select', + clearable: false, + value: type || types[0], + options: types.map((type) => { + return { + value: type, + label: type, + } + }), + onChange: (opt) => { + this.setState({ type: opt.value }) + }, + }) + ]) + ]) + ) +} + -- cgit v1.2.3 From b3cb675a8bd406bd16aa74ff209032075f9b31d7 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 4 Nov 2016 15:08:50 -0700 Subject: Develop import subviews --- ui/app/accounts/add.js | 2 +- ui/app/accounts/import/index.js | 42 ++++++++++++++++++++++++++--------------- ui/app/accounts/import/json.js | 27 ++++++++++++++++++++++++++ ui/app/accounts/import/seed.js | 30 +++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 ui/app/accounts/import/json.js create mode 100644 ui/app/accounts/import/seed.js (limited to 'ui/app') diff --git a/ui/app/accounts/add.js b/ui/app/accounts/add.js index 9493a4e05..898f89be2 100644 --- a/ui/app/accounts/add.js +++ b/ui/app/accounts/add.js @@ -62,7 +62,7 @@ AddAccountScreen.prototype.render = function () { } AddAccountScreen.prototype.goHome = function() { - this.props.dispatch(actions.showAccountPage()) + this.props.dispatch(actions.showAccountsPage()) } AddAccountScreen.prototype.renderNewOrImport = function() { diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js index a16b1c39d..a7c3252cd 100644 --- a/ui/app/accounts/import/index.js +++ b/ui/app/accounts/import/index.js @@ -4,6 +4,10 @@ const h = require('react-hyperscript') const connect = require('react-redux').connect import Select from 'react-select' +// Subviews +const JsonImportView = require('./json.js') +const SeedImportView = require('./seed.js') + module.exports = connect(mapStateToProps)(AccountImportSubview) function mapStateToProps (state) { @@ -31,24 +35,18 @@ AccountImportSubview.prototype.render = function () { h('div', { style: { padding: '10px', - background: 'rgb(242,242,242)', color: 'rgb(174, 174, 174)', }, }, [ - h('h3', 'SELECT TYPE'), - ]), - h('style', ` - .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label { - color: rgb(174,174,174); - } - `), + h('h3', { style: { padding: '3px' } }, 'SELECT TYPE'), + + h('style', ` + .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label { + color: rgb(174,174,174); + } + `), - h('div', { - style: { - padding: '10px', - }, - }, [ h(Select, { name: 'import-type-select', clearable: false, @@ -62,9 +60,23 @@ AccountImportSubview.prototype.render = function () { onChange: (opt) => { this.setState({ type: opt.value }) }, - }) - ]) + }), + ]), + + this.renderImportView(), ]) ) } +AccountImportSubview.prototype.renderImportView = function() { + const props = this.props + const state = this.state || {} + const { type } = state || props.types[0] + + switch (type) { + case 'HD Key Tree': + return h(SeedImportView) + default: + return h(JsonImportView) + } +} diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js new file mode 100644 index 000000000..22cf95cfd --- /dev/null +++ b/ui/app/accounts/import/json.js @@ -0,0 +1,27 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect + +module.exports = connect(mapStateToProps)(JsonImportSubview) + +function mapStateToProps (state) { + return {} +} + +inherits(JsonImportSubview, Component) +function JsonImportSubview () { + Component.call(this) +} + +JsonImportSubview.prototype.render = function () { + return ( + h('div', { + style: { + }, + }, [ + `Upload your json file here!`, + ]) + ) +} + diff --git a/ui/app/accounts/import/seed.js b/ui/app/accounts/import/seed.js new file mode 100644 index 000000000..b4a7c0afa --- /dev/null +++ b/ui/app/accounts/import/seed.js @@ -0,0 +1,30 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect + +module.exports = connect(mapStateToProps)(SeedImportSubview) + +function mapStateToProps (state) { + return {} +} + +inherits(SeedImportSubview, Component) +function SeedImportSubview () { + Component.call(this) +} + +SeedImportSubview.prototype.render = function () { + return ( + h('div', { + style: { + }, + }, [ + `Paste your seed phrase here!`, + h('textarea'), + h('br'), + h('button', 'Submit'), + ]) + ) +} + -- cgit v1.2.3 From 54c536e72cf328e1141de6cbd0eb2e1e24b7afce Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 16 Jan 2017 23:59:25 -0800 Subject: Fix message signing UI rendering [A recent PR](https://github.com/MetaMask/metamask-plugin/pull/1004) removed logic that rendered pending messages for approval. This commit fixes that. --- ui/app/conf-tx.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'ui/app') diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 8e255a867..a6e03c3ed 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -41,12 +41,13 @@ ConfirmTxScreen.prototype.render = function () { var provider = state.provider var unconfTxs = state.unconfTxs var unconfMsgs = state.unconfMsgs + var unconfTxList = txHelper(unconfTxs, unconfMsgs, network) - var index = state.index !== undefined ? state.index : 0 + var index = state.index !== undefined && unconfTxList[index] ? state.index : 0 var txData = unconfTxList[index] || {} - var txParams = txData.txParams + var txParams = txData.params || {} var isNotification = isPopupOrNotification() === 'notification' - if (!txParams) return null + if (unconfTxList.length === 0) return null return ( @@ -116,15 +117,19 @@ ConfirmTxScreen.prototype.render = function () { } function currentTxView (opts) { - if ('txParams' in opts.txData) { + const { txData } = opts + const { txParams, msgParams } = txData + + if (txParams) { // This is a pending transaction return h(PendingTx, opts) - } else if ('msgParams' in opts.txData) { + } else if (msgParams) { // This is a pending message to sign return h(PendingMsg, opts) } } ConfirmTxScreen.prototype.checkBalanceAgainstTx = function (txData) { + if (!txData.txParams) return false var state = this.props var address = txData.txParams.from || state.selectedAccount var account = state.accounts[address] -- cgit v1.2.3 From 77bd010543855fafe21ac37e282bc8137ef7a7d8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 17 Jan 2017 13:47:30 -0800 Subject: Add "import account" menu item + template view --- ui/app/actions.js | 8 ++++++++ ui/app/app.js | 11 +++++++++++ ui/app/import/index.js | 36 ++++++++++++++++++++++++++++++++++++ ui/app/reducers/app.js | 8 ++++++++ 4 files changed, 63 insertions(+) create mode 100644 ui/app/import/index.js (limited to 'ui/app') diff --git a/ui/app/actions.js b/ui/app/actions.js index 5a3968f82..1f1a707b5 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -32,11 +32,13 @@ var actions = { SHOW_INIT_MENU: 'SHOW_INIT_MENU', SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED', SHOW_INFO_PAGE: 'SHOW_INFO_PAGE', + SHOW_IMPORT_PAGE: 'SHOW_IMPORT_PAGE', unlockMetamask: unlockMetamask, unlockFailed: unlockFailed, showCreateVault: showCreateVault, showRestoreVault: showRestoreVault, showInitializeMenu: showInitializeMenu, + showImportPage, createNewVaultAndKeychain: createNewVaultAndKeychain, createNewVaultAndRestore: createNewVaultAndRestore, createNewVaultInProgress: createNewVaultInProgress, @@ -376,6 +378,12 @@ function showInitializeMenu () { } } +function showImportPage () { + return { + type: actions.SHOW_IMPORT_PAGE, + } +} + function agreeToDisclaimer () { return (dispatch) => { dispatch(this.showLoadingIndication()) diff --git a/ui/app/app.js b/ui/app/app.js index 9efe95874..c6377a2cf 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -20,6 +20,7 @@ const NoticeScreen = require('./components/notice') const generateLostAccountsNotice = require('../lib/lost-accounts-notice') // other views const ConfigScreen = require('./config') +const Import = require('./import') const InfoScreen = require('./info') const LoadingIndicator = require('./components/loading') const SandwichExpando = require('sandwich-expando') @@ -304,6 +305,13 @@ App.prototype.renderDropdown = function () { icon: h('i.fa.fa-gear.fa-lg'), }), + h(DropMenuItem, { + label: 'Import Account', + closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }), + action: () => this.props.dispatch(actions.showImportPage()), + icon: h('i.fa.fa-arrow-circle-o-up.fa-lg'), + }), + h(DropMenuItem, { label: 'Lock', closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }), @@ -411,6 +419,9 @@ App.prototype.renderPrimary = function () { case 'config': return h(ConfigScreen, {key: 'config'}) + case 'import-menu': + return h(Import, {key: 'import-menu'}) + case 'reveal-seed-conf': return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'}) diff --git a/ui/app/import/index.js b/ui/app/import/index.js new file mode 100644 index 000000000..89c79bedc --- /dev/null +++ b/ui/app/import/index.js @@ -0,0 +1,36 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect + +module.exports = connect(mapStateToProps)(ImportIndex) + +function mapStateToProps (state) { + return {} +} + +inherits(ImportIndex, Component) +function ImportIndex () { + Component.call(this) +} + +ImportIndex.prototype.render = function () { + const props = this.props + + + return ( + + h('.accounts-section.flex-grow', [ + + // subtitle and nav + h('.section-title.flex-center', [ + h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { + onClick: this.goHome.bind(this), + }), + h('h2.page-subtitle', 'Select Account'), + ]), + + ]) + ) +} + diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index dc7344b3e..cfa98442a 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -99,6 +99,14 @@ function reduceApp (state, action) { transForward: action.value, }) + case actions.SHOW_IMPORT_PAGE: + return extend(appState, { + currentView: { + name: 'import-menu', + }, + transForward: true, + }) + case actions.SHOW_INFO_PAGE: return extend(appState, { currentView: { -- cgit v1.2.3 From 1ff4894b674bbcbac1998228454129018e4642b6 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 17 Jan 2017 16:22:22 -0800 Subject: Allow importing of private key strings Fixes #1021 A top-right menu item now allows `Account Import`. It has a menu (with one item for now) that allows importing a private key string. Errors are displayed, and a success navigates the user to their account list, where the imported account is labeled `LOOSE`. --- ui/app/accounts/import/index.js | 21 ++++++++--- ui/app/accounts/import/private-key.js | 69 +++++++++++++++++++++++++++++++++++ ui/app/accounts/index.js | 3 +- ui/app/actions.js | 10 ++++- 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 ui/app/accounts/import/private-key.js (limited to 'ui/app') diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js index a7c3252cd..18a6b985c 100644 --- a/ui/app/accounts/import/index.js +++ b/ui/app/accounts/import/index.js @@ -7,12 +7,17 @@ import Select from 'react-select' // Subviews const JsonImportView = require('./json.js') const SeedImportView = require('./seed.js') +const PrivateKeyImportView = require('./private-key.js') + +const menuItems = [ + 'Private Key', +] module.exports = connect(mapStateToProps)(AccountImportSubview) function mapStateToProps (state) { return { - types: state.metamask.keyringTypes, + menuItems, } } @@ -24,7 +29,7 @@ function AccountImportSubview () { AccountImportSubview.prototype.render = function () { const props = this.props const state = this.state || {} - const { types } = props + const { menuItems } = props const { type } = state return ( @@ -50,8 +55,8 @@ AccountImportSubview.prototype.render = function () { h(Select, { name: 'import-type-select', clearable: false, - value: type || types[0], - options: types.map((type) => { + value: type || menuItems[0], + options: menuItems.map((type) => { return { value: type, label: type, @@ -71,11 +76,15 @@ AccountImportSubview.prototype.render = function () { AccountImportSubview.prototype.renderImportView = function() { const props = this.props const state = this.state || {} - const { type } = state || props.types[0] + const { type } = state + const { menuItems } = props + const current = type || menuItems[0] - switch (type) { + switch (current) { case 'HD Key Tree': return h(SeedImportView) + case 'Private Key': + return h(PrivateKeyImportView) default: return h(JsonImportView) } diff --git a/ui/app/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js new file mode 100644 index 000000000..6b988a76b --- /dev/null +++ b/ui/app/accounts/import/private-key.js @@ -0,0 +1,69 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const h = require('react-hyperscript') +const connect = require('react-redux').connect +const type = 'Simple Key Pair' +const actions = require('../../actions') + +module.exports = connect(mapStateToProps)(PrivateKeyImportView) + +function mapStateToProps (state) { + return { + error: state.appState.warning, + } +} + +inherits(PrivateKeyImportView, Component) +function PrivateKeyImportView () { + Component.call(this) +} + +PrivateKeyImportView.prototype.render = function () { + const { error } = this.props + + return ( + h('div', { + style: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + padding: '5px 15px 0px 15px', + }, + }, [ + h('span', 'Paste your private key string here'), + + h('input.large-input.letter-spacey', { + type: 'password', + id: 'private-key-box', + onKeyPress: this.createKeyringOnEnter.bind(this), + style: { + width: 260, + marginTop: 12, + }, + }), + + h('button.primary', { + onClick: this.createNewKeychain.bind(this), + style: { + margin: 12, + }, + }, 'Import'), + + error ? h('span.warning', error) : null, + ]) + ) +} + +PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) { + if (event.key === 'Enter') { + event.preventDefault() + this.createNewKeychain() + } +} + +PrivateKeyImportView.prototype.createNewKeychain = function () { + const input = document.getElementById('private-key-box') + const privateKey = input.value + this.props.dispatch(actions.addNewKeyring(type, [ privateKey ])) +} + diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js index 5ab31a1c0..e6f376735 100644 --- a/ui/app/accounts/index.js +++ b/ui/app/accounts/index.js @@ -73,7 +73,8 @@ AccountsScreen.prototype.render = function () { const simpleAddress = identity.address.substring(2).toLowerCase() const keyring = keyrings.find((kr) => { - return kr.accounts.includes(simpleAddress) + return kr.accounts.includes(simpleAddress) || + kr.accounts.includes(identity.address) }) return h(AccountListItem, { diff --git a/ui/app/actions.js b/ui/app/actions.js index 87b02966b..7934a329a 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -253,7 +253,15 @@ function requestRevealSeed (password) { } function addNewKeyring (type, opts) { - return callBackgroundThenUpdate(background.addNewKeyring, type, opts) + return (dispatch) => { + dispatch(actions.showLoadingIndication()) + background.addNewKeyring(type, opts, (err, newState) => { + dispatch(actions.hideLoadingIndication()) + if (err) return dispatch(actions.displayWarning(err.message)) + dispatch(actions.updateMetamaskState(newState)) + dispatch(actions.showAccountsPage()) + }) + } } function navigateToNewAccountScreen() { -- cgit v1.2.3 From 9ed6381c5ddee646b9473dbebc55893cebdeb21f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 17 Jan 2017 16:31:12 -0800 Subject: Remove unused UI files --- ui/app/accounts/add.js | 79 -------------------------------------------------- ui/app/accounts/new.js | 30 ------------------- 2 files changed, 109 deletions(-) delete mode 100644 ui/app/accounts/add.js delete mode 100644 ui/app/accounts/new.js (limited to 'ui/app') diff --git a/ui/app/accounts/add.js b/ui/app/accounts/add.js deleted file mode 100644 index 898f89be2..000000000 --- a/ui/app/accounts/add.js +++ /dev/null @@ -1,79 +0,0 @@ -const inherits = require('util').inherits -const Component = require('react').Component -const h = require('react-hyperscript') -const connect = require('react-redux').connect -const actions = require('../actions') - -// Components -const TabBar = require('../components/tab-bar') - -// Subviews -const NewAccountView = require('./new') -const ImportAccountView = require('./import') - -module.exports = connect(mapStateToProps)(AddAccountScreen) - -function mapStateToProps (state) { - return {} -} - -inherits(AddAccountScreen, Component) -function AddAccountScreen () { - Component.call(this) -} - -AddAccountScreen.prototype.render = function () { - - return ( - h('.flex-column', { - style: { - }, - }, [ - - // title and nav - h('.flex-row.space-between', { - style: { - alignItems: 'center', - padding: '0px 20px', - }, - }, [ - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: this.goHome.bind(this), - }), - h('h2.page-subtitle', 'Add Account'), - h('i', { style: { width: '18px' } }), - ]), - - h(TabBar, { - tabs: [ - { content: 'Create New', key: 'new' }, - { content: 'Import', key: 'import' }, - ], - defaultTab: 'new', - tabSelected: (key) => { - this.setState({ subview: key }) - }, - }), - - this.renderNewOrImport(), - - ]) - ) -} - -AddAccountScreen.prototype.goHome = function() { - this.props.dispatch(actions.showAccountsPage()) -} - -AddAccountScreen.prototype.renderNewOrImport = function() { - const state = this.state || {} - const subview = state.subview || 'new' - - switch (subview) { - case 'new': - return h(NewAccountView) - - case 'import': - return h(ImportAccountView) - } -} diff --git a/ui/app/accounts/new.js b/ui/app/accounts/new.js deleted file mode 100644 index 07fc1e672..000000000 --- a/ui/app/accounts/new.js +++ /dev/null @@ -1,30 +0,0 @@ -const inherits = require('util').inherits -const Component = require('react').Component -const h = require('react-hyperscript') -const connect = require('react-redux').connect - -module.exports = connect(mapStateToProps)(COMPONENTNAME) - -function mapStateToProps (state) { - return {} -} - -inherits(COMPONENTNAME, Component) -function COMPONENTNAME () { - Component.call(this) -} - -COMPONENTNAME.prototype.render = function () { - const props = this.props - - return ( - h('div', { - style: { - background: 'red', - }, - }, [ - `Hello, ${props.sender}`, - ]) - ) -} - -- cgit v1.2.3 From 693aa50e7f98e6cd1a0f0b463bc7dbbe3a3e13d3 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 17 Jan 2017 16:35:11 -0800 Subject: Remove outdated reference --- ui/app/app.js | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ui/app') diff --git a/ui/app/app.js b/ui/app/app.js index 67c78b31c..0e04c334c 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -33,7 +33,6 @@ const QrView = require('./components/qr-code') const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete') const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation') -const AddAccountScreen = require('./accounts/add') module.exports = connect(mapStateToProps)(App) @@ -408,9 +407,6 @@ App.prototype.renderPrimary = function () { case 'accountDetail': return h(AccountDetailScreen, {key: 'account-detail'}) - case 'new-account': - return h(AddAccountScreen, {key: 'new-account'}) - case 'sendTransaction': return h(SendTransactionScreen, {key: 'send-transaction'}) -- cgit v1.2.3 From 3572708fda9583df32cf19f692d797a40065ee75 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 17 Jan 2017 16:37:36 -0800 Subject: Fix test to log out despite number of menu items --- ui/app/info.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app') diff --git a/ui/app/info.js b/ui/app/info.js index cc753b2ea..e79580be4 100644 --- a/ui/app/info.js +++ b/ui/app/info.js @@ -110,7 +110,7 @@ InfoScreen.prototype.render = function () { onClick (event) { this.navigateTo(event.target.href) }, }, [ h('img.icon-size', { - src: manifest.icons[128], + src: manifest.icons['128'], style: { filter: 'grayscale(100%)', /* IE6-9 */ WebkitFilter: 'grayscale(100%)', /* Microsoft Edge and Firefox 35+ */ -- cgit v1.2.3