Merge branch 'master' into i3326-addtokenscreendesignupdate

feature/default_network_editable
Dan 7 years ago
commit 1779cff65b
  1. 2
      README.md
  2. 32
      app/scripts/lib/setupRaven.js
  3. 3
      app/scripts/vendor/raven.min.js
  4. 6
      gulpfile.js
  5. 68
      package-lock.json
  6. 9
      package.json
  7. 23
      test/integration/lib/add-token.js
  8. 6
      test/integration/lib/confirm-sig-requests.js
  9. 8
      test/integration/lib/send-new-ui.js
  10. 4
      ui/app/accounts/import/json.js
  11. 4
      ui/app/accounts/import/private-key.js
  12. 4
      ui/app/accounts/new-account/create-form.js
  13. 4
      ui/app/actions.js
  14. 10
      ui/app/add-token.js
  15. 8
      ui/app/components/customize-gas-modal/index.js
  16. 41
      ui/app/components/ens-input.js
  17. 4
      ui/app/components/modals/account-details-modal.js
  18. 2
      ui/app/components/modals/deposit-ether-modal.js
  19. 6
      ui/app/components/modals/export-private-key-modal.js
  20. 4
      ui/app/components/send/send-v2-container.js
  21. 2
      ui/app/components/shapeshift-form.js
  22. 4
      ui/app/components/signature-request.js
  23. 6
      ui/app/components/tx-view.js
  24. 2
      ui/app/components/wallet-view.js
  25. 17
      ui/app/css/itcss/components/add-token.scss
  26. 84
      ui/app/css/itcss/components/buttons.scss
  27. 3
      ui/app/css/itcss/components/hero-balance.scss
  28. 13
      ui/app/css/itcss/components/modal.scss
  29. 25
      ui/app/css/itcss/components/new-account.scss
  30. 32
      ui/app/css/itcss/components/request-signature.scss
  31. 8
      ui/app/css/itcss/components/send.scss
  32. 36
      ui/app/css/itcss/components/settings.scss
  33. 2
      ui/app/css/itcss/generic/index.scss
  34. 2
      ui/app/css/itcss/settings/variables.scss
  35. 4
      ui/app/reducers/metamask.js
  36. 24
      ui/app/send-v2.js
  37. 8
      ui/app/settings.js
  38. 44
      yarn.lock

@ -1,5 +1,5 @@
# MetaMask Browser Extension # MetaMask Browser Extension
[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](http://waffle.io/MetaMask/metamask-extension) [![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](https://waffle.io/MetaMask/metamask-extension)
## Support ## Support

@ -1,4 +1,4 @@
const Raven = require('../vendor/raven.min.js') const Raven = require('raven-js')
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505'
const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496'
@ -18,9 +18,35 @@ function setupRaven(opts) {
ravenTarget = PROD ravenTarget = PROD
} }
Raven.config(ravenTarget, { const client = Raven.config(ravenTarget, {
release, release,
}).install() transport: function(opts) {
// modify report urls
const report = opts.data
rewriteReportUrls(report)
// make request normally
client._makeRequest(opts)
},
})
client.install()
return Raven return Raven
} }
function rewriteReportUrls(report) {
// update request url
report.request.url = toMetamaskUrl(report.request.url)
// update exception stack trace
report.exception.values.forEach(item => {
item.stacktrace.frames.forEach(frame => {
frame.filename = toMetamaskUrl(frame.filename)
})
})
}
function toMetamaskUrl(origUrl) {
const filePath = origUrl.split(location.origin)[1]
if (!filePath) return origUrl
const metamaskUrl = `metamask${filePath}`
return metamaskUrl
}

File diff suppressed because one or more lines are too long

@ -339,7 +339,7 @@ function generateBundler(opts, performBundle) {
const browserifyOpts = assign({}, watchify.args, { const browserifyOpts = assign({}, watchify.args, {
entries: ['./app/scripts/'+opts.filename], entries: ['./app/scripts/'+opts.filename],
plugin: 'browserify-derequire', plugin: 'browserify-derequire',
debug: debug, debug: true,
fullPaths: debug, fullPaths: debug,
}) })
@ -405,13 +405,13 @@ function bundleTask(opts) {
.pipe(buffer()) .pipe(buffer())
// sourcemaps // sourcemaps
// loads map from browserify file // loads map from browserify file
.pipe(gulpif(debug, sourcemaps.init({ loadMaps: true }))) .pipe(sourcemaps.init({ loadMaps: true }))
// Minification // Minification
.pipe(gulpif(opts.isBuild, uglify({ .pipe(gulpif(opts.isBuild, uglify({
mangle: { reserved: [ 'MetamaskInpageProvider' ] }, mangle: { reserved: [ 'MetamaskInpageProvider' ] },
}))) })))
// writes .map file // writes .map file
.pipe(gulpif(debug, sourcemaps.write('./'))) .pipe(sourcemaps.write(debug ? './' : '../../sourcemaps'))
// write completed bundles // write completed bundles
.pipe(gulp.dest('./dist/firefox/scripts')) .pipe(gulp.dest('./dist/firefox/scripts'))
.pipe(gulp.dest('./dist/chrome/scripts')) .pipe(gulp.dest('./dist/chrome/scripts'))

68
package-lock.json generated

@ -182,6 +182,48 @@
"through2": "2.0.3" "through2": "2.0.3"
} }
}, },
"@sentry/cli": {
"version": "1.30.3",
"resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-1.30.3.tgz",
"integrity": "sha1-AtD3eBwe5eG+WkMSoyX76LGzcjE=",
"dev": true,
"requires": {
"https-proxy-agent": "2.2.0",
"node-fetch": "1.7.3",
"progress": "2.0.0",
"proxy-from-env": "1.0.0"
},
"dependencies": {
"agent-base": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
"integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==",
"dev": true,
"requires": {
"es6-promisify": "5.0.0"
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"https-proxy-agent": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz",
"integrity": "sha512-uUWcfXHvy/dwfM9bqa6AozvAjS32dZSTUYd/4SEpYKRg6LEcPLshksnQYRudM9AyNvUARMfAg5TLjUDyX/K4vA==",
"dev": true,
"requires": {
"agent-base": "4.2.0",
"debug": "3.1.0"
}
}
}
},
"@types/node": { "@types/node": {
"version": "8.5.5", "version": "8.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz",
@ -4932,6 +4974,21 @@
"event-emitter": "0.3.5" "event-emitter": "0.3.5"
} }
}, },
"es6-promise": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
"integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
"dev": true
},
"es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
"es6-promise": "4.2.4"
}
},
"es6-set": { "es6-set": {
"version": "0.1.5", "version": "0.1.5",
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
@ -16914,6 +16971,12 @@
} }
} }
}, },
"proxy-from-env": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
"dev": true
},
"prr": { "prr": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@ -17237,6 +17300,11 @@
"eve-raphael": "0.5.0" "eve-raphael": "0.5.0"
} }
}, },
"raven-js": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.0.tgz",
"integrity": "sha512-+/ygcWib8PXAE7Xq53j1tYxCgkzFyp9z05LYAKp2PA9KwO4Ek74q1tkGwZyPWI/FoXOgas6jNtQ7O3tdPif6uA=="
},
"raw-body": { "raw-body": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",

@ -29,6 +29,13 @@
"test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js", "test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js",
"test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js", "test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js",
"test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js", "test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js",
"sentry": "export RELEASE=`cat app/manifest.json| jq -r .version` && npm run sentry:release && npm run sentry:upload",
"sentry:release": "npm run sentry:release:new && npm run sentry:release:clean",
"sentry:release:new": "sentry-cli releases --org 'metamask' --project 'metamask' new $RELEASE",
"sentry:release:clean": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE delete --all",
"sentry:upload": "npm run sentry:upload:source && npm run sentry:upload:maps",
"sentry:upload:source": "for FILEPATH in ./dist/chrome/scripts/*.js; do [ -e $FILEPATH ] || continue; export FILE=`basename $FILEPATH` && echo uploading $FILE && sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload $FILEPATH metamask/scripts/$FILE; done;",
"sentry:upload:maps": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload-sourcemaps ./dist/sourcemaps/ --url-prefix 'sourcemaps' --rewrite",
"lint": "gulp lint", "lint": "gulp lint",
"lint:fix": "gulp lint:fix", "lint:fix": "gulp lint:fix",
"disc": "gulp disc --debug", "disc": "gulp disc --debug",
@ -144,6 +151,7 @@
"pumpify": "^1.3.4", "pumpify": "^1.3.4",
"qrcode-npm": "0.0.3", "qrcode-npm": "0.0.3",
"ramda": "^0.24.1", "ramda": "^0.24.1",
"raven-js": "^3.24.0",
"react": "^15.6.2", "react": "^15.6.2",
"react-addons-css-transition-group": "^15.6.0", "react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.6.2", "react-dom": "^15.6.2",
@ -179,6 +187,7 @@
"xtend": "^4.0.1" "xtend": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@sentry/cli": "^1.30.3",
"babel-core": "^6.24.1", "babel-core": "^6.24.1",
"babel-eslint": "^8.0.0", "babel-eslint": "^8.0.0",
"babel-plugin-transform-async-to-generator": "^6.24.1", "babel-plugin-transform-async-to-generator": "^6.24.1",

@ -26,7 +26,7 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok($('.token-list-item').length === 0, 'no tokens added') assert.ok($('.token-list-item').length === 0, 'no tokens added')
// Go to Add Token screen // Go to Add Token screen
let addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button') let addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present') assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click() addTokenButton[0].click()
@ -38,14 +38,14 @@ async function runAddTokenFlowTest (assert, done) {
assert.equal(addTokenTitle[0].textContent, 'Add Tokens', 'add token title is correct') assert.equal(addTokenTitle[0].textContent, 'Add Tokens', 'add token title is correct')
// Cancel Add Token // Cancel Add Token
const cancelAddTokenButton = await queryAsync($, 'button.btn-cancel.add-token__button--cancel') const cancelAddTokenButton = await queryAsync($, 'button.btn-secondary--lg.add-token__cancel-button')
assert.ok(cancelAddTokenButton[0], 'cancel add token button present') assert.ok(cancelAddTokenButton[0], 'cancel add token button present')
cancelAddTokenButton.click() cancelAddTokenButton.click()
assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view') assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view')
// Return to Add Token Screen // Return to Add Token Screen
addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button') addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present') assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click() addTokenButton[0].click()
@ -68,7 +68,7 @@ async function runAddTokenFlowTest (assert, done) {
tokenWrapper[0].click() tokenWrapper[0].click()
// Click Next button // Click Next button
let nextButton = await queryAsync($, 'button.btn-clear.add-token__button') let nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered') assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click() nextButton[0].click()
@ -78,8 +78,8 @@ async function runAddTokenFlowTest (assert, done) {
'Would you like to add these tokens?', 'Would you like to add these tokens?',
'confirm add token rendered' 'confirm add token rendered'
) )
assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found') assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
$('button.btn-clear.add-token__button')[0].click() $('button.btn-primary--lg')[0].click()
// Verify added token image // Verify added token image
let heroBalance = await queryAsync($, '.hero-balance') let heroBalance = await queryAsync($, '.hero-balance')
@ -87,7 +87,7 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added') assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added')
// Return to Add Token Screen // Return to Add Token Screen
addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button') addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present') assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click() addTokenButton[0].click()
@ -103,14 +103,15 @@ async function runAddTokenFlowTest (assert, done) {
reactTriggerChange(customInput[0]) reactTriggerChange(customInput[0])
// Click Next button // Click Next button
nextButton = await queryAsync($, 'button.btn-clear.add-token__button') nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered') assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click() nextButton[0].click()
// Verify symbol length error since contract address won't return symbol // Verify symbol length error since contract address won't return symbol
const errorMessage = await queryAsync($, '.add-token__add-custom-error-message') const errorMessage = await queryAsync($, '.add-token__add-custom-error-message')
assert.ok(errorMessage[0], 'error rendered') assert.ok(errorMessage[0], 'error rendered')
$('button.btn-cancel.add-token__button--cancel')[0].click()
$('button.btn-secondary--lg')[0].click()
// // Confirm Add token // // Confirm Add token
// assert.equal( // assert.equal(
@ -118,8 +119,8 @@ async function runAddTokenFlowTest (assert, done) {
// 'Would you like to add these tokens?', // 'Would you like to add these tokens?',
// 'confirm add token rendered' // 'confirm add token rendered'
// ) // )
// assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found') // assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
// $('button.btn-clear.add-token__button')[0].click() // $('button.btn-primary--lg')[0].click()
// // Verify added token image // // Verify added token image
// heroBalance = await queryAsync($, '.hero-balance') // heroBalance = await queryAsync($, '.hero-balance')

@ -27,7 +27,7 @@ async function runConfirmSigRequestsTest(assert, done) {
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value') let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/)) assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
let confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button') let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click() confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline') confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@ -39,7 +39,7 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigRowValue = await queryAsync($, '.request-signature__row-value') confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0') assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button') confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click() confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline') confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@ -49,7 +49,7 @@ async function runConfirmSigRequestsTest(assert, done) {
assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!') assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
assert.equal(confirmSigRowValue[1].textContent, '1337') assert.equal(confirmSigRowValue[1].textContent, '1337')
confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button') confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click() confirmSigSignButton[0].click()
const txView = await queryAsync($, '.tx-view') const txView = await queryAsync($, '.tx-view')

@ -21,13 +21,15 @@ global.ethQuery = {
sendTransaction: () => {}, sendTransaction: () => {},
} }
global.ethereumProvider = {}
async function runSendFlowTest(assert, done) { async function runSendFlowTest(assert, done) {
console.log('*** start runSendFlowTest') console.log('*** start runSendFlowTest')
const selectState = await queryAsync($, 'select') const selectState = await queryAsync($, 'select')
selectState.val('send new ui') selectState.val('send new ui')
reactTriggerChange(selectState[0]) reactTriggerChange(selectState[0])
const sendScreenButton = await queryAsync($, 'button.btn-clear.hero-balance-button') const sendScreenButton = await queryAsync($, 'button.btn-primary.hero-balance-button')
assert.ok(sendScreenButton[1], 'send screen button present') assert.ok(sendScreenButton[1], 'send screen button present')
sendScreenButton[1].click() sendScreenButton[1].click()
@ -120,7 +122,7 @@ async function runSendFlowTest(assert, done) {
'send gas field should show customized gas total converted to USD' 'send gas field should show customized gas total converted to USD'
) )
const sendButton = await queryAsync($, 'button.btn-clear.page-container__footer-button') const sendButton = await queryAsync($, 'button.btn-primary--lg.page-container__footer-button')
assert.equal(sendButton[0].textContent, 'Next', 'next button rendered') assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
sendButton[0].click() sendButton[0].click()
await timeout() await timeout()
@ -161,7 +163,7 @@ async function runSendFlowTest(assert, done) {
sendAmountFieldInputInEdit.val('1.0') sendAmountFieldInputInEdit.val('1.0')
reactTriggerChange(sendAmountFieldInputInEdit[0]) reactTriggerChange(sendAmountFieldInputInEdit[0])
const sendButtonInEdit = await queryAsync($, '.btn-clear.page-container__footer-button') const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered') assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
sendButtonInEdit[0].click() sendButtonInEdit[0].click()

@ -50,13 +50,13 @@ class JsonImportSubview extends Component {
h('div.new-account-create-form__buttons', {}, [ h('div.new-account-create-form__buttons', {}, [
h('button.new-account-create-form__button-cancel', { h('button.btn-secondary.new-account-create-form__button', {
onClick: () => this.props.goHome(), onClick: () => this.props.goHome(),
}, [ }, [
t('cancel'), t('cancel'),
]), ]),
h('button.new-account-create-form__button-create', { h('button.btn-primary.new-account-create-form__button', {
onClick: () => this.createNewKeychain(), onClick: () => this.createNewKeychain(),
}, [ }, [
t('import'), t('import'),

@ -48,13 +48,13 @@ PrivateKeyImportView.prototype.render = function () {
h('div.new-account-import-form__buttons', {}, [ h('div.new-account-import-form__buttons', {}, [
h('button.new-account-create-form__button-cancel.allcaps', { h('button.btn-secondary--lg.new-account-create-form__button', {
onClick: () => goHome(), onClick: () => goHome(),
}, [ }, [
t('cancel'), t('cancel'),
]), ]),
h('button.new-account-create-form__button-create.allcaps', { h('button.btn-primary--lg.new-account-create-form__button', {
onClick: () => this.createNewKeychain(), onClick: () => this.createNewKeychain(),
}, [ }, [
t('import'), t('import'),

@ -38,13 +38,13 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__buttons', {}, [ h('div.new-account-create-form__buttons', {}, [
h('button.new-account-create-form__button-cancel.allcaps', { h('button.btn-secondary--lg.new-account-create-form__button', {
onClick: () => this.props.goHome(), onClick: () => this.props.goHome(),
}, [ }, [
t('cancel'), t('cancel'),
]), ]),
h('button.new-account-create-form__button-create.allcaps', { h('button.btn-primary--lg.new-account-create-form__button', {
onClick: () => this.props.createAccount(newAccountName || defaultAccountName), onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
}, [ }, [
t('create'), t('create'),

@ -694,10 +694,10 @@ function updateSendFrom (from) {
} }
} }
function updateSendTo (to) { function updateSendTo (to, nickname = '') {
return { return {
type: actions.UPDATE_SEND_TO, type: actions.UPDATE_SEND_TO,
value: to, value: { to, nickname },
} }
} }

@ -323,10 +323,10 @@ AddTokenScreen.prototype.renderConfirmation = function () {
]), ]),
]), ]),
h('div.add-token__buttons', [ h('div.add-token__buttons', [
h('button.btn-cancel.add-token__button', { h('button.btn-secondary--lg.add-token__cancel-button', {
onClick: () => this.setState({ isShowingConfirmation: false }), onClick: () => this.setState({ isShowingConfirmation: false }),
}, t('back')), }, t('back')),
h('button.btn-clear.add-token__button', { h('button.btn-primary--lg', {
onClick: () => addTokens(tokens).then(goHome), onClick: () => addTokens(tokens).then(goHome),
}, t('addTokens')), }, t('addTokens')),
]), ]),
@ -402,16 +402,16 @@ AddTokenScreen.prototype.render = function () {
]), ]),
]), ]),
//
isShowingConfirmation isShowingConfirmation
? this.renderConfirmation() ? this.renderConfirmation()
: this.renderTabs(), : this.renderTabs(),
!isShowingConfirmation && h('div.add-token__buttons', [ !isShowingConfirmation && h('div.add-token__buttons', [
h('button.btn-cancel.add-token__button--cancel', { h('button.btn-secondary--lg.add-token__cancel-button', {
onClick: goHome, onClick: goHome,
}, t('cancel')), }, t('cancel')),
h('button.btn-clear.add-token__button', { h('button.btn-primary--lg.add-token__confirm-button', {
onClick: this.onNext, onClick: this.onNext,
}, t('next')), }, t('next')),
]), ]),

@ -302,12 +302,16 @@ CustomizeGasModal.prototype.render = function () {
}, [t('revert')]), }, [t('revert')]),
h('div.send-v2__customize-gas__buttons', [ h('div.send-v2__customize-gas__buttons', [
h('div.send-v2__customize-gas__cancel.allcaps', { h('button.btn-secondary.send-v2__customize-gas__cancel', {
onClick: this.props.hideModal, onClick: this.props.hideModal,
style: {
marginRight: '10px',
},
}, [t('cancel')]), }, [t('cancel')]),
h(`div.send-v2__customize-gas__save${error ? '__error' : ''}.allcaps`, { h('button.btn-primary.send-v2__customize-gas__save', {
onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal), onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal),
className: error && 'btn-primary--disabled',
}, [t('save')]), }, [t('save')]),
]), ]),

@ -9,6 +9,7 @@ const networkMap = require('ethjs-ens/lib/network-map.json')
const ensRE = /.+\..+$/ const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
const t = require('../../i18n') const t = require('../../i18n')
const ToAutoComplete = require('./send/to-autocomplete')
module.exports = EnsInput module.exports = EnsInput
@ -22,12 +23,14 @@ EnsInput.prototype.render = function () {
const props = this.props const props = this.props
const opts = extend(props, { const opts = extend(props, {
list: 'addresses', list: 'addresses',
onChange: () => { onChange: (recipient) => {
const network = this.props.network const network = this.props.network
const networkHasEnsSupport = getNetworkEnsSupport(network) const networkHasEnsSupport = getNetworkEnsSupport(network)
if (!networkHasEnsSupport) return if (!networkHasEnsSupport) return
const recipient = document.querySelector('input[name="address"]').value props.onChange(recipient)
if (recipient.match(ensRE) === null) { if (recipient.match(ensRE) === null) {
return this.setState({ return this.setState({
loadingEns: false, loadingEns: false,
@ -39,34 +42,13 @@ EnsInput.prototype.render = function () {
this.setState({ this.setState({
loadingEns: true, loadingEns: true,
}) })
this.checkName() this.checkName(recipient)
}, },
}) })
return h('div', { return h('div', {
style: { width: '100%' }, style: { width: '100%', position: 'relative' },
}, [ }, [
h('input.large-input.send-screen-input', opts), h(ToAutoComplete, { ...opts }),
// The address book functionality.
h('datalist#addresses',
[
// Corresponds to the addresses owned.
Object.keys(props.identities).map((key) => {
const identity = props.identities[key]
return h('option', {
value: identity.address,
label: identity.name,
key: identity.address,
})
}),
// Corresponds to previously sent-to addresses.
props.addressBook.map((identity) => {
return h('option', {
value: identity.address,
label: identity.name,
key: identity.address,
})
}),
]),
this.ensIcon(), this.ensIcon(),
]) ])
} }
@ -83,8 +65,7 @@ EnsInput.prototype.componentDidMount = function () {
} }
} }
EnsInput.prototype.lookupEnsName = function () { EnsInput.prototype.lookupEnsName = function (recipient) {
const recipient = document.querySelector('input[name="address"]').value
const { ensResolution } = this.state const { ensResolution } = this.state
log.info(`ENS attempting to resolve name: ${recipient}`) log.info(`ENS attempting to resolve name: ${recipient}`)
@ -130,8 +111,8 @@ EnsInput.prototype.ensIcon = function (recipient) {
title: hoverText, title: hoverText,
style: { style: {
position: 'absolute', position: 'absolute',
padding: '9px', top: '16px',
transform: 'translatex(-40px)', left: '-25px',
}, },
}, this.ensIconContents(recipient)) }, this.ensIconContents(recipient))
} }

@ -63,12 +63,12 @@ AccountDetailsModal.prototype.render = function () {
h('div.account-modal-divider'), h('div.account-modal-divider'),
h('button.btn-clear.account-modal__button', { h('button.btn-primary.account-modal__button', {
onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }), onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }),
}, t('etherscanView')), }, t('etherscanView')),
// Holding on redesign for Export Private Key functionality // Holding on redesign for Export Private Key functionality
h('button.btn-clear.account-modal__button', { h('button.btn-primary.account-modal__button', {
onClick: () => showExportPrivateKeyModal(), onClick: () => showExportPrivateKeyModal(),
}, t('exportPrivateKey')), }, t('exportPrivateKey')),

@ -94,7 +94,7 @@ DepositEtherModal.prototype.renderRow = function ({
]), ]),
!hideButton && h('div.deposit-ether-modal__buy-row__button', [ !hideButton && h('div.deposit-ether-modal__buy-row__button', [
h('button.deposit-ether-modal__deposit-button', { h('button.btn-primary--lg.deposit-ether-modal__deposit-button', {
onClick: onButtonClick, onClick: onButtonClick,
}, [buttonLabel]), }, [buttonLabel]),
]), ]),

@ -81,14 +81,14 @@ ExportPrivateKeyModal.prototype.renderButton = function (className, onClick, lab
ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) { ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) {
return h('div.export-private-key-buttons', {}, [ return h('div.export-private-key-buttons', {}, [
!privateKey && this.renderButton( !privateKey && this.renderButton(
'btn-cancel export-private-key__button export-private-key__button--cancel', 'btn-secondary--lg export-private-key__button export-private-key__button--cancel',
() => hideModal(), () => hideModal(),
'Cancel' 'Cancel'
), ),
(privateKey (privateKey
? this.renderButton('btn-clear export-private-key__button', () => hideModal(), t('done')) ? this.renderButton('btn-primary--lg export-private-key__button', () => hideModal(), t('done'))
: this.renderButton('btn-clear export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm')) : this.renderButton('btn-primary--lg export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm'))
), ),
]) ])

@ -69,13 +69,13 @@ function mapDispatchToProps (dispatch) {
updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)), updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)),
updateTx: txData => dispatch(actions.updateTransaction(txData)), updateTx: txData => dispatch(actions.updateTransaction(txData)),
setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)), setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)),
addToAddressBook: address => dispatch(actions.addToAddressBook(address)), addToAddressBook: (address, nickname) => dispatch(actions.addToAddressBook(address, nickname)),
updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)), updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)),
updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)), updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)),
updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)), updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)),
updateSendTokenBalance: tokenBalance => dispatch(actions.updateSendTokenBalance(tokenBalance)), updateSendTokenBalance: tokenBalance => dispatch(actions.updateSendTokenBalance(tokenBalance)),
updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)), updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)),
updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)), updateSendTo: (newTo, nickname) => dispatch(actions.updateSendTo(newTo, nickname)),
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)), updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)), updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)), updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),

@ -236,7 +236,7 @@ ShapeshiftForm.prototype.render = function () {
]), ]),
!depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', { !depositAddress && h('button.btn-primary--lg.shapeshift-form__shapeshift-buy-btn', {
className: btnClass, className: btnClass,
disabled: !token, disabled: !token,
onClick: () => this.onBuyWithShapeShift(), onClick: () => this.onBuyWithShapeShift(),

@ -223,10 +223,10 @@ SignatureRequest.prototype.renderFooter = function () {
} }
return h('div.request-signature__footer', [ return h('div.request-signature__footer', [
h('button.request-signature__footer__cancel-button', { h('button.btn-secondary--lg.request-signature__footer__cancel-button', {
onClick: cancel, onClick: cancel,
}, t('cancel')), }, t('cancel')),
h('button.request-signature__footer__sign-button', { h('button.btn-primary--lg', {
onClick: sign, onClick: sign,
}, t('sign')), }, t('sign')),
]) ])

@ -69,13 +69,13 @@ TxView.prototype.renderButtons = function () {
return !selectedToken return !selectedToken
? ( ? (
h('div.flex-row.flex-center.hero-balance-buttons', [ h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-clear.hero-balance-button.allcaps', { h('button.btn-primary.hero-balance-button', {
onClick: () => showModal({ onClick: () => showModal({
name: 'DEPOSIT_ETHER', name: 'DEPOSIT_ETHER',
}), }),
}, t('deposit')), }, t('deposit')),
h('button.btn-clear.hero-balance-button.allcaps', { h('button.btn-primary.hero-balance-button', {
style: { style: {
marginLeft: '0.8em', marginLeft: '0.8em',
}, },
@ -85,7 +85,7 @@ TxView.prototype.renderButtons = function () {
) )
: ( : (
h('div.flex-row.flex-center.hero-balance-buttons', [ h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-clear.hero-balance-button', { h('button.btn-primary.hero-balance-button', {
onClick: showSendTokenPage, onClick: showSendTokenPage,
}, t('send')), }, t('send')),
]) ])

@ -168,7 +168,7 @@ WalletView.prototype.render = function () {
h(TokenList), h(TokenList),
h('button.btn-clear.wallet-view__add-token-button', { h('button.btn-primary.wallet-view__add-token-button', {
onClick: () => { onClick: () => {
showAddTokenPage() showAddTokenPage()
hideSidebar() hideSidebar()

@ -261,20 +261,13 @@
padding-top: 20px; padding-top: 20px;
} }
&__button, &__confirm-button,
&__button--cancel { &__cancel-button {
margin: 0 12px; margin: 0 12px;
padding: 10px 13px; padding: 10px 13px;
height: 44px; height: 54px;
width: 133px; width: 133px;
border: 1px solid $curious-blue; margin-right: 1.2rem;
border-radius: 2px;
font-color: $curious-blue;
}
&__button--cancel {
border-color: $dusty-gray;
font-color: $dusty-gray;
} }
&__token-icons-title { &__token-icons-title {
@ -442,7 +435,7 @@
} }
&__buttons { &__buttons {
padding: 12px 0; padding: 1rem;
margin: 0; margin: 0;
border-top: 1px solid $gallery; border-top: 1px solid $gallery;
width: 100%; width: 100%;

@ -2,6 +2,76 @@
Buttons Buttons
*/ */
.btn-primary,
.btn-primary--lg,
.btn-secondary,
.btn-secondary--lg {
background: $white;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
transition: border-color .3s ease;
padding: 0 20px;
min-width: 140px;
text-transform: uppercase;
}
.btn-primary,
.btn-primary--lg {
color: $curious-blue;
border: 2px solid $spindle;
&:active {
background: $zumthor;
border-color: $curious-blue;
}
&:hover {
border-color: $curious-blue;
}
&--disabled,
&[disabled] {
cursor: auto;
opacity: .5;
pointer-events: none;
}
}
.btn-secondary,
.btn-secondary--lg {
color: $scorpion;
border: 2px solid $dusty-gray;
&:active {
background: $gallery;
border-color: $dusty-gray;
}
&:hover {
border-color: $scorpion;
}
&--disabled,
&[disabled] {
cursor: auto;
opacity: .5;
pointer-events: none;
}
}
.btn-primary, .btn-secondary {
height: 44px;
}
.btn-primary--lg, .btn-secondary--lg {
height: 54px;
}
.btn-green { .btn-green {
background-color: #02c9b1; // TODO: reusable color in colors.css background-color: #02c9b1; // TODO: reusable color in colors.css
} }
@ -130,20 +200,6 @@ button.btn-thin {
font-size: 13px; font-size: 13px;
} }
.btn-secondary {
border: 1px solid #979797;
border-radius: 2px;
background-color: $white;
font-size: 16px;
line-height: 24px;
padding: 16px 42px;
&[disabled] {
background-color: $white !important;
opacity: .5;
}
}
.btn-tertiary { .btn-tertiary {
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 2px; border-radius: 2px;

@ -103,10 +103,11 @@
} }
.hero-balance-button { .hero-balance-button {
min-width: initial;
width: 6rem; width: 6rem;
@media #{$sub-mid-size-breakpoint-range} { @media #{$sub-mid-size-breakpoint-range} {
padding: 0.4rem; padding: .4rem;
width: 4rem; width: 4rem;
display: flex; display: flex;
flex: 1; flex: 1;

@ -261,7 +261,7 @@
.account-modal__button { .account-modal__button {
margin-top: 17px; margin-top: 17px;
padding: 10px 22px; padding: 10px 22px;
width: 235px; width: 286px;
} }
} }
@ -341,9 +341,8 @@
.export-private-key__button { .export-private-key__button {
margin-top: 17px; margin-top: 17px;
padding: 10px 22px;
width: 141px; width: 141px;
height: 54px; min-width: initial;
} }
.export-private-key__button--cancel { .export-private-key__button--cancel {
@ -765,15 +764,7 @@
} }
&__deposit-button, .shapeshift-form__shapeshift-buy-btn { &__deposit-button, .shapeshift-form__shapeshift-buy-btn {
height: 54px;
width: 257px; width: 257px;
border: 1px solid $curious-blue;
border-radius: 4px;
display: flex;
justify-content: center;
font-size: 16px;
color: $curious-blue;
background-color: $white;
} }
.shapeshift-form-wrapper { .shapeshift-form-wrapper {

@ -192,29 +192,8 @@
justify-content: space-between; justify-content: space-between;
} }
&__button-cancel, &__button {
&__button-create {
height: 55px;
width: 150px; width: 150px;
border-radius: 2px; min-width: initial;
background-color: #FFFFFF;
}
&__button-cancel {
border: 1px solid $dusty-gray;
color: $dusty-gray;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
text-align: center;
}
&__button-create {
border: 1px solid $curious-blue;
color: $curious-blue;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
text-align: center;
} }
} }

@ -190,41 +190,19 @@
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-evenly; justify-content: center;
font-size: 22px; font-size: 22px;
position: relative; position: relative;
flex: 0 0 auto; flex: 0 0 auto;
border-top: 1px solid $geyser; border-top: 1px solid $geyser;
padding: 1.6rem;
&__cancel-button, button {
&__sign-button { width: 165px;
display: flex;
align-items: center;
justify-content: center;
flex: 1 0 auto;
font-family: Roboto;
font-size: 16px;
font-weight: 300;
height: 55px;
line-height: 32px;
cursor: pointer;
border-radius: 2px;
box-shadow: none;
max-width: 162px;
margin: 12px;
} }
&__cancel-button { &__cancel-button {
background: none; margin-right: 1.2rem;
border: 1px solid $dusty-gray;
margin-right: 6px;
}
&__sign-button {
background-color: $caribbean-green;
border-width: 0;
color: $white;
margin-left: 6px;
} }
} }
} }

@ -782,7 +782,6 @@
&__buttons { &__buttons {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
width: 181.75px;
margin-right: 21.25px; margin-right: 21.25px;
} }
@ -800,13 +799,8 @@
} }
&__cancel, &__save, &__save__error { &__cancel, &__save, &__save__error {
height: 34.64px;
width: 85.74px; width: 85.74px;
border: 1px solid $dusty-gray; min-width: initial;
border-radius: 2px;
font-family: 'DIN OT';
font-size: 12px;
color: $dusty-gray;
} }
&__save__error { &__save__error {

@ -130,24 +130,32 @@
cursor: pointer; cursor: pointer;
} }
.settings__clear-button { .settings__button--red {
font-size: 16px; border-color: lighten($monzo, 10%);
border: 1px solid $curious-blue; color: $monzo;
color: $curious-blue;
border-radius: 2px; &:active {
padding: 18px; background: lighten($monzo, 55%);
background-color: $white; border-color: $monzo;
text-transform: uppercase;
} }
.settings__clear-button--red { &:hover {
border: 1px solid $monzo; border-color: $monzo;
color: $monzo; }
}
.settings__button--orange {
border-color: lighten($ecstasy, 20%);
color: $ecstasy;
&:active {
background: lighten($ecstasy, 40%);
border-color: $ecstasy;
} }
.settings__clear-button--orange { &:hover {
border: 1px solid rgba(247, 134, 28, 1); border-color: $ecstasy;
color: rgba(247, 134, 28, 1); }
} }
.settings__info-logo-wrapper { .settings__info-logo-wrapper {

@ -132,7 +132,7 @@ input.large-input {
height: 55px; height: 55px;
font-size: 1rem; font-size: 1rem;
text-transform: uppercase; text-transform: uppercase;
margin-right: 1rem; margin-right: 1.2rem;
border-radius: 2px; border-radius: 2px;
&:last-of-type { &:last-of-type {

@ -52,6 +52,8 @@ $wild-strawberry: #ff4a8d;
$cornflower-blue: #7057ff; $cornflower-blue: #7057ff;
$saffron: #f6c343; $saffron: #f6c343;
$dodger-blue: #3099f2; $dodger-blue: #3099f2;
$zumthor: #edf7ff;
$ecstasy: #f7861c;
/* /*
Z-Indicies Z-Indicies

@ -39,6 +39,7 @@ function reduceMetamask (state, action) {
maxModeOn: false, maxModeOn: false,
editingTransactionId: null, editingTransactionId: null,
forceGasMin: null, forceGasMin: null,
toNickname: '',
}, },
coinOptions: {}, coinOptions: {},
useBlockie: false, useBlockie: false,
@ -238,7 +239,8 @@ function reduceMetamask (state, action) {
return extend(metamaskState, { return extend(metamaskState, {
send: { send: {
...metamaskState.send, ...metamaskState.send,
to: action.value, to: action.value.to,
toNickname: action.value.nickname,
}, },
}) })

@ -7,7 +7,7 @@ const ethAbi = require('ethereumjs-abi')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const FromDropdown = require('./components/send/from-dropdown') const FromDropdown = require('./components/send/from-dropdown')
const ToAutoComplete = require('./components/send/to-autocomplete') const EnsInput = require('./components/ens-input')
const CurrencyDisplay = require('./components/send/currency-display') const CurrencyDisplay = require('./components/send/currency-display')
const MemoTextArea = require('./components/send/memo-textarea') const MemoTextArea = require('./components/send/memo-textarea')
const GasFeeDisplay = require('./components/send/gas-fee-display-v2') const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
@ -253,7 +253,7 @@ SendTransactionScreen.prototype.renderFromRow = function () {
]) ])
} }
SendTransactionScreen.prototype.handleToChange = function (to) { SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
const { const {
updateSendTo, updateSendTo,
updateSendErrors, updateSendErrors,
@ -269,12 +269,12 @@ SendTransactionScreen.prototype.handleToChange = function (to) {
toError = t('fromToSame') toError = t('fromToSame')
} }
updateSendTo(to) updateSendTo(to, nickname)
updateSendErrors({ to: toError }) updateSendErrors({ to: toError })
} }
SendTransactionScreen.prototype.renderToRow = function () { SendTransactionScreen.prototype.renderToRow = function () {
const { toAccounts, errors, to } = this.props const { toAccounts, errors, to, network } = this.props
const { toDropdownOpen } = this.state const { toDropdownOpen } = this.state
@ -289,7 +289,10 @@ SendTransactionScreen.prototype.renderToRow = function () {
]), ]),
h('div.send-v2__form-field', [ h('div.send-v2__form-field', [
h(ToAutoComplete, { h(EnsInput, {
name: 'address',
placeholder: 'Recipient Address',
network,
to, to,
accounts: Object.entries(toAccounts).map(([key, account]) => account), accounts: Object.entries(toAccounts).map(([key, account]) => account),
dropdownOpen: toDropdownOpen, dropdownOpen: toDropdownOpen,
@ -510,13 +513,13 @@ SendTransactionScreen.prototype.renderFooter = function () {
const noErrors = !amountError && toError === null const noErrors = !amountError && toError === null
return h('div.page-container__footer', [ return h('div.page-container__footer', [
h('button.btn-cancel.page-container__footer-button', { h('button.btn-secondary--lg.page-container__footer-button', {
onClick: () => { onClick: () => {
clearSend() clearSend()
goHome() goHome()
}, },
}, t('cancel')), }, t('cancel')),
h('button.btn-clear.page-container__footer-button', { h('button.btn-primary--lg.page-container__footer-button', {
disabled: !noErrors || !gasTotal || missingTokenBalance, disabled: !noErrors || !gasTotal || missingTokenBalance,
onClick: event => this.onSubmit(event), onClick: event => this.onSubmit(event),
}, t('next')), }, t('next')),
@ -538,11 +541,11 @@ SendTransactionScreen.prototype.render = function () {
) )
} }
SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress) { SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress, nickname = '') {
const { toAccounts, addToAddressBook } = this.props const { toAccounts, addToAddressBook } = this.props
if (!toAccounts.find(({ address }) => newAddress === address)) { if (!toAccounts.find(({ address }) => newAddress === address)) {
// TODO: nickname, i.e. addToAddressBook(recipient, nickname) // TODO: nickname, i.e. addToAddressBook(recipient, nickname)
addToAddressBook(newAddress) addToAddressBook(newAddress, nickname)
} }
} }
@ -603,6 +606,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
updateTx, updateTx,
selectedToken, selectedToken,
editingTransactionId, editingTransactionId,
toNickname,
errors: { amount: amountError, to: toError }, errors: { amount: amountError, to: toError },
} = this.props } = this.props
@ -612,7 +616,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
return return
} }
this.addToAddressBookIfNew(to) this.addToAddressBookIfNew(to, toNickname)
if (editingTransactionId) { if (editingTransactionId) {
const editedTx = this.getEditedTx() const editedTx = this.getEditedTx()

@ -200,7 +200,7 @@ class Settings extends Component {
]), ]),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button', { h('button.btn-primary--lg.settings__button', {
onClick (event) { onClick (event) {
window.logStateString((err, result) => { window.logStateString((err, result) => {
if (err) { if (err) {
@ -225,7 +225,7 @@ class Settings extends Component {
h('div.settings__content-item', t('revealSeedWords')), h('div.settings__content-item', t('revealSeedWords')),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--red', { h('button.btn-primary--lg.settings__button--red', {
onClick (event) { onClick (event) {
event.preventDefault() event.preventDefault()
revealSeedConfirmation() revealSeedConfirmation()
@ -245,7 +245,7 @@ class Settings extends Component {
h('div.settings__content-item', t('useOldUI')), h('div.settings__content-item', t('useOldUI')),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--orange', { h('button.btn-primary--lg.settings__button--orange', {
onClick (event) { onClick (event) {
event.preventDefault() event.preventDefault()
setFeatureFlagToBeta() setFeatureFlagToBeta()
@ -264,7 +264,7 @@ class Settings extends Component {
h('div.settings__content-item', t('resetAccount')), h('div.settings__content-item', t('resetAccount')),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--orange', { h('button.btn-primary--lg.settings__button--orange', {
onClick (event) { onClick (event) {
event.preventDefault() event.preventDefault()
showResetAccountConfirmationModal() showResetAccountConfirmationModal()

@ -72,6 +72,15 @@
normalize-path "^2.0.1" normalize-path "^2.0.1"
through2 "^2.0.3" through2 "^2.0.3"
"@sentry/cli@^1.30.3":
version "1.30.3"
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.30.3.tgz#02d0f7781c1ee5e1be5a4312a325fbe8b1b37231"
dependencies:
https-proxy-agent "^2.1.1"
node-fetch "^1.7.3"
progress "2.0.0"
proxy-from-env "^1.0.0"
"@types/node@*": "@types/node@*":
version "8.5.2" version "8.5.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5"
@ -201,6 +210,12 @@ agent-base@2:
extend "~3.0.0" extend "~3.0.0"
semver "~5.0.1" semver "~5.0.1"
agent-base@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce"
dependencies:
es6-promisify "^5.0.0"
ajv-keywords@^1.1.1: ajv-keywords@^1.1.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
@ -3711,6 +3726,16 @@ es6-map@^0.1.3:
es6-symbol "~3.1.1" es6-symbol "~3.1.1"
event-emitter "~0.3.5" event-emitter "~0.3.5"
es6-promise@^4.0.3:
version "4.2.4"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
dependencies:
es6-promise "^4.0.3"
es6-set@~0.1.5: es6-set@~0.1.5:
version "0.1.5" version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
@ -5919,6 +5944,13 @@ https-proxy-agent@1:
debug "2" debug "2"
extend "3" extend "3"
https-proxy-agent@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz#7fbba856be8cd677986f42ebd3664f6317257887"
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
human-standard-token-abi@^1.0.2: human-standard-token-abi@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-1.0.2.tgz#207d7846796ee5bb85fdd336e769cb38045b2ae0" resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-1.0.2.tgz#207d7846796ee5bb85fdd336e769cb38045b2ae0"
@ -7984,7 +8016,7 @@ nock@^9.0.14:
qs "^6.5.1" qs "^6.5.1"
semver "^5.3.0" semver "^5.3.0"
node-fetch@^1.0.1, node-fetch@~1.7.1: node-fetch@^1.0.1, node-fetch@^1.7.3, node-fetch@~1.7.1:
version "1.7.3" version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
dependencies: dependencies:
@ -8991,7 +9023,7 @@ process@~0.5.1:
version "0.5.2" version "0.5.2"
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
progress@^2.0.0: progress@2.0.0, progress@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
@ -9067,6 +9099,10 @@ proxy-agent@~2.0.0:
pac-proxy-agent "1" pac-proxy-agent "1"
socks-proxy-agent "2" socks-proxy-agent "2"
proxy-from-env@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
prr@~1.0.1: prr@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
@ -9245,6 +9281,10 @@ raphael@^2.2.0:
dependencies: dependencies:
eve-raphael "0.5.0" eve-raphael "0.5.0"
raven-js@^3.24.0:
version "3.24.0"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.0.tgz#59464d8bc4b3812ae87a282e9bb98ecad5b4b047"
raw-body@2, raw-body@2.3.2: raw-body@2, raw-body@2.3.2:
version "2.3.2" version "2.3.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"

Loading…
Cancel
Save