aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app')
-rw-r--r--ui/app/actions.js149
-rw-r--r--ui/app/app.js74
-rw-r--r--ui/app/components/account-dropdowns.js5
-rw-r--r--ui/app/components/dropdowns/components/dropdown.js4
-rw-r--r--ui/app/components/editable-label.js1
-rw-r--r--ui/app/components/ens-input.js2
-rw-r--r--ui/app/components/identicon.js2
-rw-r--r--ui/app/components/menu-droppo.js2
-rw-r--r--ui/app/components/notice.js2
-rw-r--r--ui/app/css/itcss/components/sections.scss4
-rw-r--r--ui/app/keychains/hd/create-vault-complete.js9
-rw-r--r--ui/app/reducers/app.js10
-rw-r--r--ui/app/reducers/metamask.js24
13 files changed, 237 insertions, 51 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 169fac78a..48ebc240e 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -183,9 +183,12 @@ var actions = {
showLoadingIndication: showLoadingIndication,
hideLoadingIndication: hideLoadingIndication,
// buy Eth with coinbase
+ onboardingBuyEthView,
+ ONBOARDING_BUY_ETH_VIEW: 'ONBOARDING_BUY_ETH_VIEW',
BUY_ETH: 'BUY_ETH',
buyEth: buyEth,
buyEthView: buyEthView,
+ buyWithShapeShift,
BUY_ETH_VIEW: 'BUY_ETH_VIEW',
COINBASE_SUBVIEW: 'COINBASE_SUBVIEW',
coinBaseSubview: coinBaseSubview,
@@ -270,14 +273,18 @@ function confirmSeedWords () {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
log.debug(`background.clearSeedWordCache`)
- background.clearSeedWordCache((err, account) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
+ return new Promise((resolve, reject) => {
+ background.clearSeedWordCache((err, account) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ reject(err)
+ }
- log.info('Seed word cache cleared. ' + account)
- dispatch(actions.showAccountDetail(account))
+ log.info('Seed word cache cleared. ' + account)
+ dispatch(actions.showAccountsPage())
+ resolve(account)
+ })
})
}
}
@@ -286,10 +293,20 @@ function createNewVaultAndRestore (password, seed) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
log.debug(`background.createNewVaultAndRestore`)
- background.createNewVaultAndRestore(password, seed, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.showAccountsPage())
+
+ return new Promise((resolve, reject) => {
+ background.createNewVaultAndRestore(password, seed, (err) => {
+
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+
+ dispatch(actions.showAccountsPage())
+ resolve()
+ })
})
}
}
@@ -298,19 +315,26 @@ function createNewVaultAndKeychain (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
log.debug(`background.createNewVaultAndKeychain`)
- background.createNewVaultAndKeychain(password, (err) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- log.debug(`background.placeSeedWords`)
- background.placeSeedWords((err) => {
+
+ return new Promise((resolve, reject) => {
+ background.createNewVaultAndKeychain(password, (err) => {
if (err) {
- return dispatch(actions.displayWarning(err.message))
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
}
- dispatch(actions.hideLoadingIndication())
- forceUpdateMetamaskState(dispatch)
+ log.debug(`background.placeSeedWords`)
+ background.placeSeedWords((err) => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+ dispatch(actions.hideLoadingIndication())
+ forceUpdateMetamaskState(dispatch)
+ resolve()
+ })
})
})
+
}
}
@@ -354,18 +378,25 @@ function importNewAccount (strategy, args) {
return (dispatch) => {
dispatch(actions.showLoadingIndication('This may take a while, be patient.'))
log.debug(`background.importAccountWithStrategy`)
- background.importAccountWithStrategy(strategy, args, (err) => {
- if (err) return dispatch(actions.displayWarning(err.message))
- log.debug(`background.getState`)
- background.getState((err, newState) => {
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ background.importAccountWithStrategy(strategy, args, (err) => {
if (err) {
- return dispatch(actions.displayWarning(err.message))
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
}
- dispatch(actions.updateMetamaskState(newState))
- dispatch({
- type: actions.SHOW_ACCOUNT_DETAIL,
- value: newState.selectedAddress,
+ log.debug(`background.getState`)
+ background.getState((err, newState) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch({
+ type: actions.SHOW_ACCOUNT_DETAIL,
+ value: newState.selectedAddress,
+ })
+ resolve(newState)
})
})
})
@@ -948,21 +979,23 @@ function goBackToInitView () {
function markNoticeRead (notice) {
return (dispatch) => {
- dispatch(this.showLoadingIndication())
+ dispatch(actions.showLoadingIndication())
log.debug(`background.markNoticeRead`)
- background.markNoticeRead(notice, (err, notice) => {
- dispatch(this.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err))
- }
- if (notice) {
- return dispatch(actions.showNotice(notice))
- } else {
- dispatch(this.clearNotices())
- return {
- type: actions.SHOW_ACCOUNTS_PAGE,
+ return new Promise((resolve, reject) => {
+ background.markNoticeRead(notice, (err, notice) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err))
+ return reject(err)
}
- }
+ if (notice) {
+ dispatch(actions.showNotice(notice))
+ resolve()
+ } else {
+ dispatch(actions.clearNotices())
+ resolve()
+ }
+ })
})
}
}
@@ -1214,6 +1247,13 @@ function buyEth (opts) {
}
}
+function onboardingBuyEthView (address) {
+ return {
+ type: actions.ONBOARDING_BUY_ETH_VIEW,
+ value: address,
+ }
+}
+
function buyEthView (address) {
return {
type: actions.BUY_ETH_VIEW,
@@ -1279,6 +1319,18 @@ function coinShiftRquest (data, marketData) {
}
}
+function buyWithShapeShift (data) {
+ return dispatch => new Promise((resolve, reject) => {
+ shapeShiftRequest('shift', { method: 'POST', data}, (response) => {
+ if (response.error) {
+ return reject(response.error)
+ }
+ background.createShapeShiftTx(response.deposit, response.depositType)
+ return resolve(response)
+ })
+ })
+}
+
function showQrView (data, message) {
return {
type: actions.SHOW_QR_VIEW,
@@ -1315,9 +1367,14 @@ function shapeShiftRequest (query, options, cb) {
options.method ? method = options.method : method = 'GET'
var requestListner = function (request) {
- queryResponse = JSON.parse(this.responseText)
- cb ? cb(queryResponse) : null
- return queryResponse
+ try {
+ queryResponse = JSON.parse(this.responseText)
+ cb ? cb(queryResponse) : null
+ return queryResponse
+ } catch (e) {
+ cb ? cb({error: e}) : null
+ return e
+ }
}
var shapShiftReq = new XMLHttpRequest()
diff --git a/ui/app/app.js b/ui/app/app.js
index 0cfbb5af5..7cf5c7b9d 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -4,6 +4,9 @@ const connect = require('react-redux').connect
const h = require('react-hyperscript')
const { checkFeatureToggle } = require('../lib/feature-toggle-utils')
const actions = require('./actions')
+// mascara
+const MascaraFirstTime = require('../../mascara/src/app/first-time').default
+const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
// init
const InitializeMenuScreen = require('./first-time/init-menu')
const NewKeyChainScreen = require('./new-keychain')
@@ -50,6 +53,9 @@ function mapStateToProps (state) {
accounts,
address,
keyrings,
+ isInitialized,
+ noActiveNotices,
+ seedWords,
} = state.metamask
const selected = address || Object.keys(accounts)[0]
@@ -66,6 +72,8 @@ function mapStateToProps (state) {
currentView: state.appState.currentView,
activeAddress: state.appState.activeAddress,
transForward: state.appState.transForward,
+ isMascara: state.metamask.isMascara,
+ isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
seedWords: state.metamask.seedWords,
unapprovedTxs: state.metamask.unapprovedTxs,
unapprovedMsgs: state.metamask.unapprovedMsgs,
@@ -140,6 +148,8 @@ App.prototype.render = function () {
(isLoading || isLoadingNetwork) && h(Loading, {
loadingMessage: loadMessage,
}),
+
+ // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
// content
this.renderPrimary(),
@@ -216,6 +226,22 @@ App.prototype.renderAppBar = function () {
if (window.METAMASK_UI_TYPE === 'notification') {
return null
}
+
+ const props = this.props
+ const state = this.state || {}
+ const isNetworkMenuOpen = state.isNetworkMenuOpen || false
+ const {isMascara, isOnboarding} = props
+
+ // Do not render header if user is in mascara onboarding
+ if (isMascara && isOnboarding) {
+ return null
+ }
+
+ // Do not render header if user is in mascara buy ether
+ if (isMascara && props.currentView.name === 'buyEth') {
+ return null
+ }
+
return (
h('.full-width', {
@@ -282,6 +308,17 @@ App.prototype.renderAppBar = function () {
}
+App.prototype.renderLoadingIndicator = function ({ isLoading, isLoadingNetwork, loadMessage }) {
+ const { isMascara } = this.props
+
+ return isMascara
+ ? null
+ : h(Loading, {
+ isLoading: isLoading || isLoadingNetwork,
+ loadingMessage: loadMessage,
+ })
+}
+
App.prototype.renderBackButton = function (style, justArrow = false) {
var props = this.props
return (
@@ -304,6 +341,11 @@ App.prototype.renderBackButton = function (style, justArrow = false) {
App.prototype.renderPrimary = function () {
log.debug('rendering primary')
var props = this.props
+ const {isMascara, isOnboarding} = props
+
+ if (isMascara && isOnboarding) {
+ return h(MascaraFirstTime)
+ }
// notices
if (!props.noActiveNotices) {
@@ -410,6 +452,38 @@ App.prototype.renderPrimary = function () {
log.debug('rendering buy ether screen')
return h(BuyView, {key: 'buyEthView'})
+ case 'onboardingBuyEth':
+ log.debug('rendering onboarding buy ether screen')
+ return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
+
+ case 'qr':
+ log.debug('rendering show qr screen')
+ return h('div', {
+ style: {
+ position: 'absolute',
+ height: '100%',
+ top: '0px',
+ left: '0px',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: () => props.dispatch(actions.backToAccountDetail(props.activeAddress)),
+ style: {
+ marginLeft: '10px',
+ marginTop: '50px',
+ },
+ }),
+ h('div', {
+ style: {
+ position: 'absolute',
+ left: '44px',
+ width: '285px',
+ },
+ }, [
+ h(QrView, {key: 'qr'}),
+ ]),
+ ])
+
default:
log.debug('rendering default, account detail screen')
return h(MainContainer, {key: 'account-detail'})
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index 1b46e532a..6abdd4757 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -297,6 +297,11 @@ AccountDropdowns.propTypes = {
identities: PropTypes.objectOf(PropTypes.object),
selected: PropTypes.string,
keyrings: PropTypes.array,
+ actions: PropTypes.objectOf(PropTypes.func),
+ network: PropTypes.string,
+ style: PropTypes.object,
+ enableAccountOptions: PropTypes.bool,
+ enableAccountsSelector: PropTypes.bool,
}
const mapDispatchToProps = (dispatch) => {
diff --git a/ui/app/components/dropdowns/components/dropdown.js b/ui/app/components/dropdowns/components/dropdown.js
index 991c89cb8..ca68e55f7 100644
--- a/ui/app/components/dropdowns/components/dropdown.js
+++ b/ui/app/components/dropdowns/components/dropdown.js
@@ -65,6 +65,9 @@ Dropdown.propTypes = {
onClick: PropTypes.func.isRequired,
children: PropTypes.node,
style: PropTypes.object.isRequired,
+ onClickOutside: PropTypes.func,
+ innerStyle: PropTypes.object,
+ useCssTransition: PropTypes.bool,
}
class DropdownMenuItem extends Component {
@@ -100,6 +103,7 @@ DropdownMenuItem.propTypes = {
closeMenu: PropTypes.func.isRequired,
onClick: PropTypes.func.isRequired,
children: PropTypes.node,
+ style: PropTypes.object,
}
module.exports = {
diff --git a/ui/app/components/editable-label.js b/ui/app/components/editable-label.js
index 167be7eaf..8a5c8954f 100644
--- a/ui/app/components/editable-label.js
+++ b/ui/app/components/editable-label.js
@@ -48,6 +48,7 @@ EditableLabel.prototype.saveIfEnter = function (event) {
}
EditableLabel.prototype.saveText = function () {
+ // eslint-disable-next-line react/no-find-dom-node
var container = findDOMNode(this)
var text = container.querySelector('.editable-label input').value
var truncatedText = text.substring(0, 20)
diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js
index fb8c8e579..6553053f7 100644
--- a/ui/app/components/ens-input.js
+++ b/ui/app/components/ens-input.js
@@ -6,7 +6,7 @@ const debounce = require('debounce')
const copyToClipboard = require('copy-to-clipboard')
const ENS = require('ethjs-ens')
const networkMap = require('ethjs-ens/lib/network-map.json')
-const ensRE = /.+\.eth$/
+const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
index 259fa4d73..d30b7cd56 100644
--- a/ui/app/components/identicon.js
+++ b/ui/app/components/identicon.js
@@ -55,6 +55,7 @@ IdenticonComponent.prototype.componentDidMount = function () {
if (!address) return
+ // eslint-disable-next-line react/no-find-dom-node
var container = findDOMNode(this)
var diameter = props.diameter || this.defaultDiameter
@@ -70,6 +71,7 @@ IdenticonComponent.prototype.componentDidUpdate = function () {
if (!address) return
+ // eslint-disable-next-line react/no-find-dom-node
var container = findDOMNode(this)
var children = container.children
diff --git a/ui/app/components/menu-droppo.js b/ui/app/components/menu-droppo.js
index 95b75f54c..c80bee2be 100644
--- a/ui/app/components/menu-droppo.js
+++ b/ui/app/components/menu-droppo.js
@@ -97,6 +97,7 @@ MenuDroppoComponent.prototype.componentDidMount = function () {
if (this && document.body) {
this.globalClickHandler = this.globalClickOccurred.bind(this)
document.body.addEventListener('click', this.globalClickHandler)
+ // eslint-disable-next-line react/no-find-dom-node
var container = findDOMNode(this)
this.container = container
}
@@ -110,6 +111,7 @@ MenuDroppoComponent.prototype.componentWillUnmount = function () {
MenuDroppoComponent.prototype.globalClickOccurred = function (event) {
const target = event.target
+ // eslint-disable-next-line react/no-find-dom-node
const container = findDOMNode(this)
if (target !== container &&
diff --git a/ui/app/components/notice.js b/ui/app/components/notice.js
index abfff1f5c..941ac33e6 100644
--- a/ui/app/components/notice.js
+++ b/ui/app/components/notice.js
@@ -117,6 +117,7 @@ Notice.prototype.render = function () {
}
Notice.prototype.componentDidMount = function () {
+ // eslint-disable-next-line react/no-find-dom-node
var node = findDOMNode(this)
linker.setupListener(node)
if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
@@ -125,6 +126,7 @@ Notice.prototype.componentDidMount = function () {
}
Notice.prototype.componentWillUnmount = function () {
+ // eslint-disable-next-line react/no-find-dom-node
var node = findDOMNode(this)
linker.teardownListener(node)
}
diff --git a/ui/app/css/itcss/components/sections.scss b/ui/app/css/itcss/components/sections.scss
index bc89fdccc..388aea175 100644
--- a/ui/app/css/itcss/components/sections.scss
+++ b/ui/app/css/itcss/components/sections.scss
@@ -39,7 +39,9 @@ textarea.twelve-word-phrase {
/* unlock */
.error {
- color: #e20202;
+ // color: #e20202;
+ color: #f7861c;
+ margin-bottom: 9px;
}
.warning {
diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js
index 745990351..5ab5d4c33 100644
--- a/ui/app/keychains/hd/create-vault-complete.js
+++ b/ui/app/keychains/hd/create-vault-complete.js
@@ -62,7 +62,8 @@ CreateVaultCompleteScreen.prototype.render = function () {
}),
h('button.primary', {
- onClick: () => this.confirmSeedWords(),
+ onClick: () => this.confirmSeedWords()
+ .then(account => this.showAccountDetail(account)),
style: {
margin: '24px',
fontSize: '0.9em',
@@ -82,5 +83,9 @@ CreateVaultCompleteScreen.prototype.render = function () {
}
CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
- this.props.dispatch(actions.confirmSeedWords())
+ return this.props.dispatch(actions.confirmSeedWords())
+}
+
+CreateVaultCompleteScreen.prototype.showAccountDetail = function (account) {
+ return this.props.dispatch(actions.showAccountDetail(account))
}
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index f10bf9fb7..6fb7f8cca 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -557,6 +557,16 @@ function reduceApp (state, action) {
},
})
+ case actions.ONBOARDING_BUY_ETH_VIEW:
+ return extend(appState, {
+ transForward: true,
+ currentView: {
+ name: 'onboardingBuyEth',
+ context: appState.currentView.name,
+ },
+ identity: state.metamask.identities[action.value],
+ })
+
case actions.COINBASE_SUBVIEW:
return extend(appState, {
buyView: {
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 8bf003e64..7408f827a 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -1,5 +1,6 @@
const extend = require('xtend')
const actions = require('../actions')
+const MetamascaraPlatform = require('../../../app/scripts/platforms/window')
module.exports = reduceMetamask
@@ -11,6 +12,7 @@ function reduceMetamask (state, action) {
isInitialized: false,
isUnlocked: false,
isAccountMenuOpen: false,
+ isMascara: window.platform instanceof MetamascaraPlatform,
rpcTarget: 'https://rawtestrpc.metamask.io/',
identities: {},
unapprovedTxs: {},
@@ -31,6 +33,7 @@ function reduceMetamask (state, action) {
memo: '',
errors: {},
},
+ coinOptions: {},
}, state.metamask)
switch (action.type) {
@@ -150,7 +153,7 @@ function reduceMetamask (state, action) {
})
case actions.UPDATE_TOKEN_EXCHANGE_RATE:
- const { payload: { pair, marketinfo } } = action
+ const { payload: { pair, marketinfo } } = action
return extend(metamaskState, {
tokenExchangeRates: {
...metamaskState.tokenExchangeRates,
@@ -250,6 +253,25 @@ function reduceMetamask (state, action) {
},
})
+ case actions.PAIR_UPDATE:
+ const { value: { marketinfo: pairMarketInfo } } = action
+ return extend(metamaskState, {
+ tokenExchangeRates: {
+ ...metamaskState.tokenExchangeRates,
+ [pairMarketInfo.pair]: pairMarketInfo,
+ },
+ })
+
+ case actions.SHAPESHIFT_SUBVIEW:
+ const { value: { marketinfo: ssMarketInfo, coinOptions } } = action
+ return extend(metamaskState, {
+ tokenExchangeRates: {
+ ...metamaskState.tokenExchangeRates,
+ [marketinfo.pair]: ssMarketInfo,
+ },
+ coinOptions,
+ })
+
default:
return metamaskState