From 06a931f9884165941d693bca20273bbe64b622ac Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 31 Oct 2017 14:01:10 -0500 Subject: ui - allow optional size for mascot --- ui/app/components/mascot.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/mascot.js b/ui/app/components/mascot.js index 973ec2cad..3b0d3e31b 100644 --- a/ui/app/components/mascot.js +++ b/ui/app/components/mascot.js @@ -7,13 +7,13 @@ const debounce = require('debounce') module.exports = Mascot inherits(Mascot, Component) -function Mascot () { +function Mascot ({width = '200', height = '200'}) { Component.call(this) this.logo = metamaskLogo({ followMouse: true, pxNotRatio: true, - width: 200, - height: 200, + width, + height, }) this.refollowMouse = debounce(this.logo.setFollowMouse.bind(this.logo, true), 1000) -- cgit From a171b9b847bf0a889d1a29f51ddd475da8061874 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 5 Dec 2017 00:46:19 +0300 Subject: Download State Logs with .json extension That doesn't fix #2095, but at least makes downloaded files syntax-highlighted when opened in editors --- ui/app/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/config.js b/ui/app/config.js index c14fa1d28..9cb2a0aad 100644 --- a/ui/app/config.js +++ b/ui/app/config.js @@ -117,7 +117,7 @@ ConfigScreen.prototype.render = function () { if (err) { state.dispatch(actions.displayWarning('Error in retrieving state logs.')) } else { - exportAsFile('MetaMask State Logs', result) + exportAsFile('MetaMask State Logs.json', result) } }) }, -- cgit From 6ff580584a74c6d85f54ce7cfc500db822904957 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 6 Dec 2017 22:20:11 -0500 Subject: Add retry background method and action --- ui/app/actions.js | 6 ++++++ ui/app/components/transaction-list-item.js | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 04fd35b20..2ab68b62d 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -168,6 +168,7 @@ var actions = { callBackgroundThenUpdate, forceUpdateMetamaskState, + retryTransaction, } module.exports = actions @@ -759,6 +760,11 @@ function markAccountsFound () { return callBackgroundThenUpdate(background.markAccountsFound) } +function retryTransaction () { + log.debug(`background.retryTransaction`) + return callBackgroundThenUpdate(background.retryTransaction) +} + // // config // diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index 891d5e227..ddef4a4ae 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -9,6 +9,7 @@ const CopyButton = require('./copyButton') const vreme = new (require('vreme'))() const Tooltip = require('./tooltip') const numberToBN = require('number-to-bn') +const actions = require('../actions') const TransactionIcon = require('./transaction-list-item-icon') const ShiftListItem = require('./shift-list-item') @@ -21,6 +22,7 @@ function TransactionListItem () { TransactionListItem.prototype.render = function () { const { transaction, network, conversionRate, currentCurrency } = this.props + const { status } = transaction if (transaction.key === 'shapeshift') { if (network === '1') return h(ShiftListItem, transaction) } @@ -32,7 +34,7 @@ TransactionListItem.prototype.render = function () { var isMsg = ('msgParams' in transaction) var isTx = ('txParams' in transaction) - var isPending = transaction.status === 'unapproved' + var isPending = status === 'unapproved' let txParams if (isTx) { txParams = transaction.txParams @@ -97,10 +99,16 @@ TransactionListItem.prototype.render = function () { showFiat: false, style: {fontSize: '15px'}, }) : h('.flex-column'), + ]) ) } +TransactionListItem.prototype.resubmit = function () { + const { transaction } = this.props + this.props.dispatch(actions.resubmitTx(transaction.id)) +} + function domainField (txParams) { return h('div', { style: { -- cgit From 500fbe450a10e1a3c756707e44225b196601372e Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 6 Dec 2017 22:22:40 -0500 Subject: Add button to retry transaction --- ui/app/components/transaction-list-item.js | 103 +++++++++++++++++++---------- 1 file changed, 69 insertions(+), 34 deletions(-) (limited to 'ui') diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index ddef4a4ae..9c512a89d 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -46,7 +46,7 @@ TransactionListItem.prototype.render = function () { const isClickable = ('hash' in transaction && isLinkable) || isPending return ( - h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, { + h('.transaction-list-item.flex-column', { onClick: (event) => { if (isPending) { this.props.showTx(transaction.id) @@ -58,48 +58,83 @@ TransactionListItem.prototype.render = function () { }, style: { padding: '20px 0', + alignItems: 'center', }, }, [ + h(`.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, { + style: { + width: '100%', + }, + }, [ + h('.identicon-wrapper.flex-column.flex-center.select-none', [ + h(TransactionIcon, { txParams, transaction, isTx, isMsg }), + ]), - h('.identicon-wrapper.flex-column.flex-center.select-none', [ - h(TransactionIcon, { txParams, transaction, isTx, isMsg }), + h(Tooltip, { + title: 'Transaction Number', + position: 'right', + }, [ + h('span', { + style: { + display: 'flex', + cursor: 'normal', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + padding: '10px', + }, + }, nonce), + ]), + + h('.flex-column', {style: {width: '200px', overflow: 'hidden'}}, [ + domainField(txParams), + h('div', date), + recipientField(txParams, transaction, isTx, isMsg), + ]), + + // Places a copy button if tx is successful, else places a placeholder empty div. + transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}), + + isTx ? h(EthBalance, { + value: txParams.value, + conversionRate, + currentCurrency, + width: '55px', + shorten: true, + showFiat: false, + style: {fontSize: '15px'}, + }) : h('.flex-column'), ]), - h(Tooltip, { - title: 'Transaction Number', - position: 'right', + transaction.status === 'submitted' && h('.transition-list-item__retry', { + onClick: event => { + event.stopPropagation() + this.resubmit() + }, + style: { + height: '30px', + borderRadius: '30px', + color: '#F9881B', + padding: '0 25px', + backgroundColor: '#FFE3C9', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + fontSize: '9px', + cursor: 'pointer', + }, }, [ - h('span', { + h('div', { style: { - display: 'flex', - cursor: 'normal', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - padding: '10px', + paddingRight: '2px', }, - }, nonce), - ]), - - h('.flex-column', {style: {width: '200px', overflow: 'hidden'}}, [ - domainField(txParams), - h('div', date), - recipientField(txParams, transaction, isTx, isMsg), + }, 'Taking too long?'), + h('div', { + style: { + textDecoration: 'underline', + }, + }, 'Retry with a higher gas price here'), ]), - - // Places a copy button if tx is successful, else places a placeholder empty div. - transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}), - - isTx ? h(EthBalance, { - value: txParams.value, - conversionRate, - currentCurrency, - width: '55px', - shorten: true, - showFiat: false, - style: {fontSize: '15px'}, - }) : h('.flex-column'), - ]) ) } -- cgit From 02736d2d361a415f145404a96f553c73e3707eb5 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 6 Dec 2017 22:48:26 -0500 Subject: Connect to redux for retryTransaction --- ui/app/components/transaction-list-item.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index 9c512a89d..56e90e26c 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -1,6 +1,7 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits +const connect = require('react-redux').connect const EthBalance = require('./eth-balance') const addressSummary = require('../util').addressSummary @@ -13,7 +14,14 @@ const actions = require('../actions') const TransactionIcon = require('./transaction-list-item-icon') const ShiftListItem = require('./shift-list-item') -module.exports = TransactionListItem + +const mapDispatchToProps = dispatch => { + return { + retryTransaction: transactionId => dispatch(actions.retryTransaction(transactionId)), + } +} + +module.exports = connect(null, mapDispatchToProps)(TransactionListItem) inherits(TransactionListItem, Component) function TransactionListItem () { @@ -141,7 +149,7 @@ TransactionListItem.prototype.render = function () { TransactionListItem.prototype.resubmit = function () { const { transaction } = this.props - this.props.dispatch(actions.resubmitTx(transaction.id)) + this.props.retryTransaction(transaction.id) } function domainField (txParams) { -- cgit From 97abbc5cbe97157304f27f0f20336b543de62428 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 6 Dec 2017 22:55:47 -0500 Subject: Fix action --- ui/app/actions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 2ab68b62d..35eb4b0c8 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -760,9 +760,9 @@ function markAccountsFound () { return callBackgroundThenUpdate(background.markAccountsFound) } -function retryTransaction () { +function retryTransaction (txId) { log.debug(`background.retryTransaction`) - return callBackgroundThenUpdate(background.retryTransaction) + return callBackgroundThenUpdate(background.retryTransaction, txId) } // -- cgit From 81fb9db1bcd08fb4e92d87d0c0905cb02dac63c2 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 6 Dec 2017 23:09:32 -0500 Subject: View tx after editing state to unconfirmed --- ui/app/actions.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 35eb4b0c8..0dc4f3832 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -762,7 +762,15 @@ function markAccountsFound () { function retryTransaction (txId) { log.debug(`background.retryTransaction`) - return callBackgroundThenUpdate(background.retryTransaction, txId) + return (dispatch) => { + background.retryTransaction(txId, (err) => { + if (err) { + return dispatch(actions.displayWarning(err.message)) + } + forceUpdateMetamaskState(dispatch) + dispatch(actions.viewPendingTx(txId)) + }) + } } // -- cgit From 31564e0a86072ae2b49923dcf28983075308c432 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 6 Dec 2017 23:20:15 -0500 Subject: Fix retry action --- ui/app/actions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 0dc4f3832..52ea899aa 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -763,11 +763,11 @@ function markAccountsFound () { function retryTransaction (txId) { log.debug(`background.retryTransaction`) return (dispatch) => { - background.retryTransaction(txId, (err) => { + background.retryTransaction(txId, (err, newState) => { if (err) { return dispatch(actions.displayWarning(err.message)) } - forceUpdateMetamaskState(dispatch) + dispatch(actions.updateMetamaskState(newState)) dispatch(actions.viewPendingTx(txId)) }) } -- cgit From 6b3909547f14533cfe09e3d12ac61f0cf57eedd4 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 6 Dec 2017 23:27:43 -0500 Subject: Fix styling of Retry buton --- ui/app/components/transaction-list-item.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ui') diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index 56e90e26c..fa6c5915d 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -120,15 +120,15 @@ TransactionListItem.prototype.render = function () { this.resubmit() }, style: { - height: '30px', - borderRadius: '30px', + height: '22px', + borderRadius: '22px', color: '#F9881B', - padding: '0 25px', + padding: '0 20px', backgroundColor: '#FFE3C9', display: 'flex', justifyContent: 'center', alignItems: 'center', - fontSize: '9px', + fontSize: '8px', cursor: 'pointer', }, }, [ -- cgit From 0e25129028dd45d717d27dfe0c06db8a4052bd4e Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 6 Dec 2017 23:42:47 -0500 Subject: Enforce retry tx at minimum gas of previous tx --- ui/app/components/pending-tx.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 5b1b367c6..51e57dcd2 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -38,6 +38,14 @@ PendingTx.prototype.render = function () { const txMeta = this.gatherTxMeta() const txParams = txMeta.txParams || {} + // Allow retry txs + const { lastGasPrice } = txMeta + let forceGasMin + if (lastGasPrice) { + const stripped = ethUtil.stripHexPrefix(lastGasPrice) + forceGasMin = new BN(stripped, 16).add(MIN_GAS_PRICE_BN) + } + // Account Details const address = txParams.from || props.selectedAddress const identity = props.identities[address] || { address: address } @@ -199,7 +207,7 @@ PendingTx.prototype.render = function () { precision: 9, scale: 9, suffix: 'GWEI', - min: MIN_GAS_PRICE_BN, + min: forceGasMin || MIN_GAS_PRICE_BN, style: { position: 'relative', top: '5px', -- cgit From b9f2f8c2a78332a2522d49baedf25e894273ef38 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 7 Dec 2017 00:01:11 -0500 Subject: Show retry button on submitted transactions greater than 30 seconds, add hover styling --- ui/app/components/transaction-list-item.js | 8 +++++++- ui/app/css/index.css | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index fa6c5915d..42ef665b1 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -28,6 +28,12 @@ function TransactionListItem () { Component.call(this) } +TransactionListItem.prototype.showRetryButton = function () { + const { transaction = {} } = this.props + const { status, time } = transaction + return status === 'submitted' && Date.now() - time > 30000 +} + TransactionListItem.prototype.render = function () { const { transaction, network, conversionRate, currentCurrency } = this.props const { status } = transaction @@ -114,7 +120,7 @@ TransactionListItem.prototype.render = function () { }) : h('.flex-column'), ]), - transaction.status === 'submitted' && h('.transition-list-item__retry', { + this.showRetryButton() && h('.transition-list-item__retry.grow-on-hover', { onClick: event => { event.stopPropagation() this.resubmit() diff --git a/ui/app/css/index.css b/ui/app/css/index.css index 0630c4c12..c0bf18c23 100644 --- a/ui/app/css/index.css +++ b/ui/app/css/index.css @@ -108,6 +108,10 @@ button:not([disabled]):active, input[type="submit"]:not([disabled]):active { transform: scale(0.95); } +.grow-on-hover:hover { + transform: scale(1.05); +} + a { text-decoration: none; color: inherit; -- cgit From c82fd990aafd72ede0c08d2820c0c1f1db6bfa81 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 7 Dec 2017 04:02:11 -0500 Subject: Add 10% price bump to retry attempts. Turns out geth requires at least a 10% price bump to replace txs: https://github.com/ethereum/go-ethereum/blob/9619a610248e9630968ba1d9be8e214b645c9c55/core/tx_pool.go#L133 --- ui/app/components/pending-tx.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 51e57dcd2..32d54902e 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -43,7 +43,9 @@ PendingTx.prototype.render = function () { let forceGasMin if (lastGasPrice) { const stripped = ethUtil.stripHexPrefix(lastGasPrice) - forceGasMin = new BN(stripped, 16).add(MIN_GAS_PRICE_BN) + const lastGas = new BN(stripped, 16) + const priceBump = lastGas.divn('10') + forceGasMin = lastGas.add(priceBump) } // Account Details -- cgit From bfec077d798aea7b2869b3ff0d292243eec60da5 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 8 Dec 2017 13:09:53 -0330 Subject: Fixes the cancel button in the buy screen to take the user home. --- ui/app/components/coinbase-form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/coinbase-form.js b/ui/app/components/coinbase-form.js index f44d86045..f70208625 100644 --- a/ui/app/components/coinbase-form.js +++ b/ui/app/components/coinbase-form.js @@ -40,7 +40,7 @@ CoinbaseForm.prototype.render = function () { }, 'Continue to Coinbase'), h('button.btn-red', { - onClick: () => props.dispatch(actions.backTobuyView(props.accounts.address)), + onClick: () => props.dispatch(actions.goHome()), }, 'Cancel'), ]), ]) -- cgit From d110c916a4dde947dcfdc610aaadf9fba251449a Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 12 Dec 2017 09:47:51 -0800 Subject: Show watched tokens with no balance --- ui/app/components/token-list.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'ui') diff --git a/ui/app/components/token-list.js b/ui/app/components/token-list.js index 998ec901d..149733b89 100644 --- a/ui/app/components/token-list.js +++ b/ui/app/components/token-list.js @@ -194,10 +194,7 @@ TokenList.prototype.componentWillUpdate = function (nextProps) { } TokenList.prototype.updateBalances = function (tokens) { - const heldTokens = tokens.filter(token => { - return token.balance !== '0' && token.string !== '0.000' - }) - this.setState({ tokens: heldTokens, isLoading: false }) + this.setState({ tokens, isLoading: false }) } TokenList.prototype.componentWillUnmount = function () { -- cgit From 0feb5b210b81533fc25c4760ce33876b4c749247 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 20 Dec 2017 14:19:13 -0330 Subject: Hides the sidebar after the an account menu actions changes the screen behind the sidebar. --- ui/app/components/account-menu/index.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui') diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index a9f075ec7..286a3b587 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -28,27 +28,33 @@ function mapDispatchToProps (dispatch) { toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()), showAccountDetail: address => { dispatch(actions.showAccountDetail(address)) + dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, lockMetamask: () => { dispatch(actions.lockMetamask()) dispatch(actions.displayWarning(null)) + dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, showConfigPage: () => { dispatch(actions.showConfigPage()) + dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, showNewAccountModal: () => { dispatch(actions.showModal({ name: 'NEW_ACCOUNT' })) + dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, showImportPage: () => { dispatch(actions.showImportPage()) + dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, showInfoPage: () => { dispatch(actions.showInfoPage()) + dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, } -- cgit From 109e4e5d96e31b52fcfdb22620bff113107d000c Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 19 Dec 2017 14:02:32 -0330 Subject: Hide fiat values on account details screen when eth/token value is 0. --- ui/app/components/balance-component.js | 3 ++- ui/app/components/token-cell.js | 4 +++- ui/app/components/tx-list-item.js | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/balance-component.js b/ui/app/components/balance-component.js index d14aa675f..50007ce14 100644 --- a/ui/app/components/balance-component.js +++ b/ui/app/components/balance-component.js @@ -94,7 +94,8 @@ BalanceComponent.prototype.renderFiatValue = function (formattedBalance) { } BalanceComponent.prototype.renderFiatAmount = function (fiatDisplayNumber, fiatSuffix, fiatPrefix) { - if (fiatDisplayNumber === 'N/A') return null + const shouldNotRenderFiat = fiatDisplayNumber === 'N/A' || Number(fiatDisplayNumber) === 0 + if (shouldNotRenderFiat) return null return h('div.fiat-amount', { style: {}, diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js index b40c0ec0d..677b66830 100644 --- a/ui/app/components/token-cell.js +++ b/ui/app/components/token-cell.js @@ -86,7 +86,9 @@ TokenCell.prototype.render = function () { numberOfDecimals: 2, conversionRate: currentTokenToFiatRate, }) - formattedFiat = `${currentTokenInFiat} ${currentCurrency.toUpperCase()}` + formattedFiat = currentTokenInFiat.toString() === '0' + ? '' + : `${currentTokenInFiat} ${currentCurrency.toUpperCase()}` } const showFiat = Boolean(currentTokenInFiat) && currentCurrency.toUpperCase() !== symbol diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js index 4e76147a1..8a9253d4d 100644 --- a/ui/app/components/tx-list-item.js +++ b/ui/app/components/tx-list-item.js @@ -170,6 +170,7 @@ TxListItem.prototype.getSendTokenTotal = async function () { TxListItem.prototype.render = function () { const { transactionStatus, + transactionAmount, onClick, transActionId, dateString, @@ -177,6 +178,7 @@ TxListItem.prototype.render = function () { className, } = this.props const { total, fiatTotal } = this.state + const showFiatTotal = transactionAmount !== '0x0' && fiatTotal return h(`div${className || ''}`, { key: transActionId, @@ -238,7 +240,7 @@ TxListItem.prototype.render = function () { }), }, total), - fiatTotal && h('span.tx-list-fiat-value', fiatTotal), + showFiatTotal && h('span.tx-list-fiat-value', fiatTotal), ]), ]), -- cgit From bccbf14b39ab2b1670c9c30b276404fe4f949cd7 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Wed, 20 Dec 2017 14:52:50 -0330 Subject: [NewUI] Hide UI toggle in mascara (#2772) * Hides old-UI on mascara. * Improve code clarity in select-app.js --- ui/app/actions.js | 7 ++----- ui/app/select-app.js | 25 +++++++++++++++---------- ui/app/settings.js | 8 +++++--- 3 files changed, 22 insertions(+), 18 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index ed0518184..e694152a2 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1523,10 +1523,7 @@ function updateTokenExchangeRate (token = '') { } } -function setFeatureFlag (feature, activated) { - const notificationType = activated - ? 'BETA_UI_NOTIFICATION_MODAL' - : 'OLD_UI_NOTIFICATION_MODAL' +function setFeatureFlag (feature, activated, notificationType) { return (dispatch) => { dispatch(actions.showLoadingIndication()) return new Promise((resolve, reject) => { @@ -1537,7 +1534,7 @@ function setFeatureFlag (feature, activated) { reject(err) } dispatch(actions.updateFeatureFlags(updatedFeatureFlags)) - dispatch(actions.showModal({ name: notificationType })) + notificationType && dispatch(actions.showModal({ name: notificationType })) resolve(updatedFeatureFlags) }) }) diff --git a/ui/app/select-app.js b/ui/app/select-app.js index 3ea93ced3..a51182f47 100644 --- a/ui/app/select-app.js +++ b/ui/app/select-app.js @@ -12,35 +12,40 @@ function mapStateToProps (state) { betaUI: state.metamask.featureFlags.betaUI, autoAdd: autoAddToBetaUI(state), isUnlocked: state.metamask.isUnlocked, + isMascara: state.metamask.isMascara, } } function mapDispatchToProps (dispatch) { return { - setFeatureFlagToBeta: () => dispatch(setFeatureFlag('betaUI', true)), + setFeatureFlagWithModal: () => dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')), + setFeatureFlagWithoutModal: () => dispatch(setFeatureFlag('betaUI', true)), } } module.exports = connect(mapStateToProps, mapDispatchToProps)(SelectedApp) inherits(SelectedApp, Component) function SelectedApp () { - this.state = { - autoAdd: false, - } Component.call(this) } SelectedApp.prototype.componentWillReceiveProps = function (nextProps) { - const { isUnlocked, setFeatureFlagToBeta } = this.props + const { + isUnlocked, + setFeatureFlagWithModal, + setFeatureFlagWithoutModal, + isMascara, + } = this.props - if (!isUnlocked && nextProps.isUnlocked && nextProps.autoAdd) { - this.setState({ autoAdd: nextProps.autoAdd }) - setFeatureFlagToBeta() + if (isMascara) { + setFeatureFlagWithoutModal() + } else if (!isUnlocked && nextProps.isUnlocked && (nextProps.autoAdd)) { + setFeatureFlagWithModal() } } SelectedApp.prototype.render = function () { - const { betaUI } = this.props - const Selected = betaUI ? App : OldApp + const { betaUI, isMascara } = this.props + const Selected = betaUI || isMascara ? App : OldApp return h(Selected) } diff --git a/ui/app/settings.js b/ui/app/settings.js index ca7535d26..74b282a98 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -250,7 +250,7 @@ class Settings extends Component { } renderSettingsContent () { - const { warning } = this.props + const { warning, isMascara } = this.props return ( h('div.settings__content', [ @@ -261,7 +261,7 @@ class Settings extends Component { this.renderNewRpcUrl(), this.renderStateLogs(), this.renderSeedWords(), - this.renderOldUI(), + !isMascara && this.renderOldUI(), ]) ) } @@ -386,12 +386,14 @@ Settings.propTypes = { setFeatureFlagToBeta: PropTypes.func, warning: PropTypes.string, goHome: PropTypes.func, + isMascara: PropTypes.bool, } const mapStateToProps = state => { return { metamask: state.metamask, warning: state.appState.warning, + isMascara: state.metamask.isMascara, } } @@ -403,7 +405,7 @@ const mapDispatchToProps = dispatch => { displayWarning: warning => dispatch(actions.displayWarning(warning)), revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()), setUseBlockie: value => dispatch(actions.setUseBlockie(value)), - setFeatureFlagToBeta: () => dispatch(actions.setFeatureFlag('betaUI', false)), + setFeatureFlagToBeta: () => dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')), } } -- cgit From 1f1fc2c49ecbb5c6a0a1d925d5c02cf48f795b2f Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 19 Dec 2017 11:16:11 -0330 Subject: Canceled, edited transactions show edited amount. --- ui/app/actions.js | 19 +++++++++++++++++++ ui/app/components/pending-tx/confirm-send-ether.js | 9 ++++++++- ui/app/components/pending-tx/confirm-send-token.js | 9 ++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index e694152a2..9d3d7184e 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -126,6 +126,7 @@ var actions = { signTx: signTx, signTokenTx: signTokenTx, updateAndApproveTx, + updateAndCancelTx, cancelTx: cancelTx, completedTx: completedTx, txError: txError, @@ -710,6 +711,24 @@ function updateAndApproveTx (txData) { } } +function updateAndCancelTx (txData) { + log.info('actions: updateAndCancelTx: ' + JSON.stringify(txData)) + return (dispatch) => { + log.debug(`actions calling background.updateAndCancelTx`) + background.updateAndCancelTransaction(txData, (err) => { + dispatch(actions.hideLoadingIndication()) + dispatch(actions.updateTransactionParams(txData.id, txData.txParams)) + dispatch(actions.clearSend()) + if (err) { + dispatch(actions.txError(err)) + dispatch(actions.goHome()) + return log.error(err.message) + } + dispatch(actions.completedTx(txData.id)) + }) + } +} + function completedTx (id) { return { type: actions.COMPLETED_TX, diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 1264da153..01195502e 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -55,6 +55,7 @@ function mapDispatchToProps (dispatch) { dispatch(actions.showSendPage()) }, cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })), + updateAndCancelTx: txMeta => dispatch(actions.updateAndCancelTx(txMeta)), } } @@ -421,7 +422,13 @@ ConfirmSendEther.prototype.onSubmit = function (event) { ConfirmSendEther.prototype.cancel = function (event, txMeta) { event.preventDefault() - this.props.cancelTransaction(txMeta) + const { send, updateAndCancelTx, cancelTransaction } = this.props + + if (send.editingTransactionId) { + updateAndCancelTx(txMeta) + } else { + cancelTransaction(txMeta) + } } ConfirmSendEther.prototype.checkValidity = function () { diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index 727cd260b..e6ce3f6e6 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -89,6 +89,7 @@ function mapDispatchToProps (dispatch, ownProps) { })) dispatch(actions.showSendTokenPage()) }, + updateAndCancelTx: txMeta => dispatch(actions.updateAndCancelTx(txMeta)), } } @@ -415,7 +416,13 @@ ConfirmSendToken.prototype.onSubmit = function (event) { ConfirmSendToken.prototype.cancel = function (event, txMeta) { event.preventDefault() - this.props.cancelTransaction(txMeta) + const { send, updateAndCancelTx, cancelTransaction } = this.props + + if (send.editingTransactionId) { + updateAndCancelTx(txMeta) + } else { + cancelTransaction(txMeta) + } } ConfirmSendToken.prototype.checkValidity = function () { -- cgit From bf4043c59bb67ea93599207d91cb7a4f4426e75f Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 20 Dec 2017 13:47:16 -0330 Subject: Adds updateTransaction to background and used it to update after editing in send-v2. --- ui/app/actions.js | 22 +++--- ui/app/components/pending-tx/confirm-send-ether.js | 29 +------- ui/app/components/pending-tx/confirm-send-token.js | 42 +----------- ui/app/components/send/send-v2-container.js | 2 + ui/app/conf-tx.js | 2 +- ui/app/send-v2.js | 78 +++++++++++++++++----- 6 files changed, 80 insertions(+), 95 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 9d3d7184e..ef8a5ec46 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -125,8 +125,8 @@ var actions = { sendTx: sendTx, signTx: signTx, signTokenTx: signTokenTx, + updateTransaction, updateAndApproveTx, - updateAndCancelTx, cancelTx: cancelTx, completedTx: completedTx, txError: txError, @@ -693,29 +693,28 @@ function signTokenTx (tokenAddress, toAddress, amount, txData) { } } -function updateAndApproveTx (txData) { - log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData)) +function updateTransaction (txData) { + log.info('actions: updateTx: ' + JSON.stringify(txData)) return (dispatch) => { - log.debug(`actions calling background.updateAndApproveTx`) - background.updateAndApproveTransaction(txData, (err) => { + log.debug(`actions calling background.updateTx`) + background.updateTransaction(txData, (err) => { dispatch(actions.hideLoadingIndication()) dispatch(actions.updateTransactionParams(txData.id, txData.txParams)) - dispatch(actions.clearSend()) if (err) { dispatch(actions.txError(err)) dispatch(actions.goHome()) return log.error(err.message) } - dispatch(actions.completedTx(txData.id)) + dispatch(actions.showConfTxPage({ id: txData.id })) }) } } -function updateAndCancelTx (txData) { - log.info('actions: updateAndCancelTx: ' + JSON.stringify(txData)) +function updateAndApproveTx (txData) { + log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData)) return (dispatch) => { - log.debug(`actions calling background.updateAndCancelTx`) - background.updateAndCancelTransaction(txData, (err) => { + log.debug(`actions calling background.updateAndApproveTx`) + background.updateAndApproveTransaction(txData, (err) => { dispatch(actions.hideLoadingIndication()) dispatch(actions.updateTransactionParams(txData.id, txData.txParams)) dispatch(actions.clearSend()) @@ -773,6 +772,7 @@ function cancelTx (txData) { return (dispatch) => { log.debug(`background.cancelTransaction`) background.cancelTransaction(txData.id, () => { + dispatch(actions.clearSend()) dispatch(actions.completedTx(txData.id)) }) } diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 01195502e..566224864 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -55,7 +55,6 @@ function mapDispatchToProps (dispatch) { dispatch(actions.showSendPage()) }, cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })), - updateAndCancelTx: txMeta => dispatch(actions.updateAndCancelTx(txMeta)), } } @@ -422,13 +421,9 @@ ConfirmSendEther.prototype.onSubmit = function (event) { ConfirmSendEther.prototype.cancel = function (event, txMeta) { event.preventDefault() - const { send, updateAndCancelTx, cancelTransaction } = this.props + const { cancelTransaction } = this.props - if (send.editingTransactionId) { - updateAndCancelTx(txMeta) - } else { - cancelTransaction(txMeta) - } + cancelTransaction(txMeta) } ConfirmSendEther.prototype.checkValidity = function () { @@ -452,26 +447,6 @@ ConfirmSendEther.prototype.gatherTxMeta = function () { const state = this.state const txData = clone(state.txData) || clone(props.txData) - if (props.send.editingTransactionId) { - const { - send: { - memo, - amount: value, - gasLimit: gas, - gasPrice, - }, - } = props - const { txParams: { from, to } } = txData - txData.txParams = { - from: ethUtil.addHexPrefix(from), - to: ethUtil.addHexPrefix(to), - memo: memo && ethUtil.addHexPrefix(memo), - value: ethUtil.addHexPrefix(value), - gas: ethUtil.addHexPrefix(gas), - gasPrice: ethUtil.addHexPrefix(gasPrice), - } - } - // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`) return txData } diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index e6ce3f6e6..a07835911 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -89,7 +89,6 @@ function mapDispatchToProps (dispatch, ownProps) { })) dispatch(actions.showSendTokenPage()) }, - updateAndCancelTx: txMeta => dispatch(actions.updateAndCancelTx(txMeta)), } } @@ -416,13 +415,9 @@ ConfirmSendToken.prototype.onSubmit = function (event) { ConfirmSendToken.prototype.cancel = function (event, txMeta) { event.preventDefault() - const { send, updateAndCancelTx, cancelTransaction } = this.props + const { send, cancelTransaction } = this.props - if (send.editingTransactionId) { - updateAndCancelTx(txMeta) - } else { - cancelTransaction(txMeta) - } + cancelTransaction(txMeta) } ConfirmSendToken.prototype.checkValidity = function () { @@ -446,39 +441,6 @@ ConfirmSendToken.prototype.gatherTxMeta = function () { const state = this.state const txData = clone(state.txData) || clone(props.txData) - if (props.send.editingTransactionId) { - const { - send: { - memo, - amount, - gasLimit: gas, - gasPrice, - to, - }, - } = props - - const { txParams: { from, to: tokenAddress } } = txData - - const tokenParams = { - from: ethUtil.addHexPrefix(from), - value: '0', - gas: ethUtil.addHexPrefix(gas), - gasPrice: ethUtil.addHexPrefix(gasPrice), - } - - const data = '0xa9059cbb' + Array.prototype.map.call( - ethAbi.rawEncode(['address', 'uint256'], [to, ethUtil.addHexPrefix(amount)]), - x => ('00' + x.toString(16)).slice(-2) - ).join('') - - txData.txParams = { - ...tokenParams, - to: ethUtil.addHexPrefix(tokenAddress), - memo: memo && ethUtil.addHexPrefix(memo), - data, - } - } - // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`) return txData } diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js index 655de8897..ff7714e82 100644 --- a/ui/app/components/send/send-v2-container.js +++ b/ui/app/components/send/send-v2-container.js @@ -50,6 +50,7 @@ function mapStateToProps (state) { data, amountConversionRate: selectedToken ? tokenToFiatRate : conversionRate, tokenContract: getSelectedTokenContract(state), + unapprovedTxs: state.metamask.unapprovedTxs, } } @@ -64,6 +65,7 @@ function mapDispatchToProps (dispatch) { ), signTx: txParams => dispatch(actions.signTx(txParams)), updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)), + updateTx: txData => dispatch(actions.updateTransaction(txData)), setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)), addToAddressBook: address => dispatch(actions.addToAddressBook(address)), updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)), diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 9f273aaec..d71e4b35f 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -115,7 +115,7 @@ function currentTxView (opts) { log.info('rendering current tx view') const { txData } = opts const { txParams, msgParams } = txData - + console.log(`22222 currentTxView txData`, txData); if (txParams) { log.debug('txParams detected, rendering pending tx') return h(PendingTx, opts) diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index e1b88f0db..617211b20 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -2,6 +2,7 @@ const { inherits } = require('util') const PersistentForm = require('../lib/persistent-form') const h = require('react-hyperscript') +const ethAbi = require('ethereumjs-abi') const ethUtil = require('ethereumjs-util') const Identicon = require('./components/identicon') @@ -552,6 +553,47 @@ SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress) { } } +SendTransactionScreen.prototype.getEditedTx = function () { + const { + from: {address: from}, + to, + amount, + gasLimit: gas, + gasPrice, + selectedToken, + editingTransactionId, + unapprovedTxs, + } = this.props + + const editingTx = unapprovedTxs[editingTransactionId] + + editingTx.txParams = { + from: ethUtil.addHexPrefix(from), + gas: ethUtil.addHexPrefix(gas), + gasPrice: ethUtil.addHexPrefix(gasPrice), + } + + if (selectedToken) { + const data = '0xa9059cbb' + Array.prototype.map.call( + ethAbi.rawEncode(['address', 'uint256'], [to, ethUtil.addHexPrefix(amount)]), + x => ('00' + x.toString(16)).slice(-2) + ).join('') + + Object.assign(editingTx.txParams, { + value: ethUtil.addHexPrefix('0'), + to: ethUtil.addHexPrefix(selectedToken.address), + data, + }) + } else { + Object.assign(editingTx.txParams, { + value: ethUtil.addHexPrefix(amount), + to: ethUtil.addHexPrefix(to), + }) + } + + return editingTx +} + SendTransactionScreen.prototype.onSubmit = function (event) { event.preventDefault() const { @@ -562,10 +604,12 @@ SendTransactionScreen.prototype.onSubmit = function (event) { gasPrice, signTokenTx, signTx, + updateTx, selectedToken, editingTransactionId, errors: { amount: amountError, to: toError }, backToConfirmScreen, + unapprovedTxs, } = this.props const noErrors = !amountError && toError === null @@ -577,23 +621,25 @@ SendTransactionScreen.prototype.onSubmit = function (event) { this.addToAddressBookIfNew(to) if (editingTransactionId) { - backToConfirmScreen(editingTransactionId) - return - } + const editedTx = this.getEditedTx() - const txParams = { - from, - value: '0', - gas, - gasPrice, - } + updateTx(editedTx) + } else { - if (!selectedToken) { - txParams.value = amount - txParams.to = to - } + const txParams = { + from, + value: '0', + gas, + gasPrice, + } - selectedToken - ? signTokenTx(selectedToken.address, to, amount, txParams) - : signTx(txParams) + if (!selectedToken) { + txParams.value = amount + txParams.to = to + } + + selectedToken + ? signTokenTx(selectedToken.address, to, amount, txParams) + : signTx(txParams) + } } -- cgit From 5fe3c5aae6756f225edd0f8646ac0a23c264a81c Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 20 Dec 2017 15:05:41 -0330 Subject: Lint fixes. --- ui/app/components/pending-tx/confirm-send-token.js | 3 +-- ui/app/components/send/send-v2-container.js | 1 - ui/app/conf-tx.js | 2 +- ui/app/send-v2.js | 2 -- 4 files changed, 2 insertions(+), 6 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index a07835911..aa4f29fb0 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -2,7 +2,6 @@ const Component = require('react').Component const { connect } = require('react-redux') const h = require('react-hyperscript') const inherits = require('util').inherits -const ethAbi = require('ethereumjs-abi') const tokenAbi = require('human-standard-token-abi') const abiDecoder = require('abi-decoder') abiDecoder.addABI(tokenAbi) @@ -415,7 +414,7 @@ ConfirmSendToken.prototype.onSubmit = function (event) { ConfirmSendToken.prototype.cancel = function (event, txMeta) { event.preventDefault() - const { send, cancelTransaction } = this.props + const { cancelTransaction } = this.props cancelTransaction(txMeta) } diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js index ff7714e82..2d2ed4546 100644 --- a/ui/app/components/send/send-v2-container.js +++ b/ui/app/components/send/send-v2-container.js @@ -79,7 +79,6 @@ function mapDispatchToProps (dispatch) { updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)), goHome: () => dispatch(actions.goHome()), clearSend: () => dispatch(actions.clearSend()), - backToConfirmScreen: editingTransactionId => dispatch(actions.showConfTxPage({ id: editingTransactionId })), setMaxModeTo: bool => dispatch(actions.setMaxModeTo(bool)), } } diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index d71e4b35f..9f273aaec 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -115,7 +115,7 @@ function currentTxView (opts) { log.info('rendering current tx view') const { txData } = opts const { txParams, msgParams } = txData - console.log(`22222 currentTxView txData`, txData); + if (txParams) { log.debug('txParams detected, rendering pending tx') return h(PendingTx, opts) diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 617211b20..1c0ff3aea 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -608,8 +608,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) { selectedToken, editingTransactionId, errors: { amount: amountError, to: toError }, - backToConfirmScreen, - unapprovedTxs, } = this.props const noErrors = !amountError && toError === null -- cgit From 9ced63584bc93cf6ac82786dec0984b5022346ae Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 20 Dec 2017 19:06:58 -0330 Subject: Add constanst for token transfer function signature. --- ui/app/components/send/send-constants.js | 3 +++ ui/app/send-v2.js | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/send/send-constants.js b/ui/app/components/send/send-constants.js index 9c240972f..b3ee0899a 100644 --- a/ui/app/components/send/send-constants.js +++ b/ui/app/components/send/send-constants.js @@ -20,6 +20,8 @@ const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT_HEX, MIN_GAS_PRICE_HEX, { multiplierBase: 16, }) +const TOKEN_TRANSFER_FUNCTION_SIGNATURE = '0xa9059cbb' + module.exports = { MIN_GAS_PRICE_GWEI, MIN_GAS_PRICE_HEX, @@ -27,4 +29,5 @@ module.exports = { MIN_GAS_LIMIT_HEX, MIN_GAS_LIMIT_DEC, MIN_GAS_TOTAL, + TOKEN_TRANSFER_FUNCTION_SIGNATURE, } diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 1c0ff3aea..cf9e709d4 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -14,6 +14,7 @@ const GasFeeDisplay = require('./components/send/gas-fee-display-v2') const { MIN_GAS_TOTAL, + TOKEN_TRANSFER_FUNCTION_SIGNATURE, } = require('./components/send/send-constants') const { @@ -574,7 +575,7 @@ SendTransactionScreen.prototype.getEditedTx = function () { } if (selectedToken) { - const data = '0xa9059cbb' + Array.prototype.map.call( + const data = TOKEN_TRANSFER_FUNCTION_SIGNATURE + Array.prototype.map.call( ethAbi.rawEncode(['address', 'uint256'], [to, ethUtil.addHexPrefix(amount)]), x => ('00' + x.toString(16)).slice(-2) ).join('') -- cgit From e7e1b7a95180597308bd167bd4a152bbbf53ff21 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 20 Dec 2017 19:11:18 -0330 Subject: Clone transaction while editing instead of mutating object from state. --- ui/app/send-v2.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'ui') diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index cf9e709d4..b7f2e7277 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -566,12 +566,13 @@ SendTransactionScreen.prototype.getEditedTx = function () { unapprovedTxs, } = this.props - const editingTx = unapprovedTxs[editingTransactionId] - - editingTx.txParams = { - from: ethUtil.addHexPrefix(from), - gas: ethUtil.addHexPrefix(gas), - gasPrice: ethUtil.addHexPrefix(gasPrice), + const editingTx = { + ...unapprovedTxs[editingTransactionId], + txParams: { + from: ethUtil.addHexPrefix(from), + gas: ethUtil.addHexPrefix(gas), + gasPrice: ethUtil.addHexPrefix(gasPrice), + } } if (selectedToken) { -- cgit From 4acd48966edf2e6cf4ced6e3e0983a44dcb2ec13 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 21 Dec 2017 23:33:01 -0330 Subject: [NewUI] Fixes tests and sends user to NewUI after registering. (#2788) * Fixes tests and sends user to NewUI after registering. * Karma config? * Empty commit * Remove unneeded json state mock file. --- ui/app/select-app.js | 9 ++++++--- ui/app/send-v2.js | 2 +- ui/index.js | 1 - 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/app/select-app.js b/ui/app/select-app.js index a51182f47..0b837b547 100644 --- a/ui/app/select-app.js +++ b/ui/app/select-app.js @@ -13,6 +13,7 @@ function mapStateToProps (state) { autoAdd: autoAddToBetaUI(state), isUnlocked: state.metamask.isUnlocked, isMascara: state.metamask.isMascara, + firstTime: Object.keys(state.metamask.identities).length === 0, } } @@ -35,9 +36,10 @@ SelectedApp.prototype.componentWillReceiveProps = function (nextProps) { setFeatureFlagWithModal, setFeatureFlagWithoutModal, isMascara, + firstTime, } = this.props - if (isMascara) { + if (isMascara || firstTime) { setFeatureFlagWithoutModal() } else if (!isUnlocked && nextProps.isUnlocked && (nextProps.autoAdd)) { setFeatureFlagWithModal() @@ -45,7 +47,8 @@ SelectedApp.prototype.componentWillReceiveProps = function (nextProps) { } SelectedApp.prototype.render = function () { - const { betaUI, isMascara } = this.props - const Selected = betaUI || isMascara ? App : OldApp + const { betaUI, isMascara, firstTime } = this.props + + const Selected = betaUI || isMascara || firstTime ? App : OldApp return h(Selected) } diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index b7f2e7277..7c9b6dbc6 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -572,7 +572,7 @@ SendTransactionScreen.prototype.getEditedTx = function () { from: ethUtil.addHexPrefix(from), gas: ethUtil.addHexPrefix(gas), gasPrice: ethUtil.addHexPrefix(gasPrice), - } + }, } if (selectedToken) { diff --git a/ui/index.js b/ui/index.js index fff677471..2aa30d3fe 100644 --- a/ui/index.js +++ b/ui/index.js @@ -8,7 +8,6 @@ global.log = require('loglevel') module.exports = launchMetamaskUi - log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn') function launchMetamaskUi (opts, cb) { -- cgit From a218008adf85dfb5fa8ca93c789e14d9f2090813 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Fri, 22 Dec 2017 10:43:02 -0800 Subject: Track usage of old and new UI (#2794) [NewUI] Track usage of old and new UI --- ui/app/actions.js | 37 +++++++++++++++++++++++++++++++++---- ui/app/reducers/metamask.js | 7 +++++++ ui/app/select-app.js | 13 ++++++++++--- ui/app/settings.js | 10 +++++++--- ui/index.js | 6 ++++++ 5 files changed, 63 insertions(+), 10 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index e8271c9a7..bd3aab45a 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -240,12 +240,17 @@ var actions = { SET_USE_BLOCKIE: 'SET_USE_BLOCKIE', setUseBlockie, - + // Feature Flags setFeatureFlag, updateFeatureFlags, UPDATE_FEATURE_FLAGS: 'UPDATE_FEATURE_FLAGS', - + + // Network + setNetworkEndpoints, + updateNetworkEndpointType, + UPDATE_NETWORK_ENDPOINT_TYPE: 'UPDATE_NETWORK_ENDPOINT_TYPE', + retryTransaction, } @@ -1489,7 +1494,7 @@ function reshowQrCode (data, coin) { dispatch(actions.showLoadingIndication()) shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => { if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error)) - + var message = [ `Deposit your ${coin} to the address bellow:`, `Deposit Limit: ${mktResponse.limit}`, @@ -1565,7 +1570,7 @@ function setFeatureFlag (feature, activated, notificationType) { dispatch(actions.hideLoadingIndication()) if (err) { dispatch(actions.displayWarning(err.message)) - reject(err) + return reject(err) } dispatch(actions.updateFeatureFlags(updatedFeatureFlags)) notificationType && dispatch(actions.showModal({ name: notificationType })) @@ -1646,3 +1651,27 @@ function setUseBlockie (val) { }) } } + +function setNetworkEndpoints (networkEndpointType) { + return dispatch => { + log.debug('background.setNetworkEndpoints') + return new Promise((resolve, reject) => { + background.setNetworkEndpoints(networkEndpointType, err => { + if (err) { + dispatch(actions.displayWarning(err.message)) + return reject(err) + } + + dispatch(actions.updateNetworkEndpointType(networkEndpointType)) + resolve(networkEndpointType) + }) + }) + } +} + +function updateNetworkEndpointType (networkEndpointType) { + return { + type: actions.UPDATE_NETWORK_ENDPOINT_TYPE, + value: networkEndpointType, + } +} diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 95b41e5f3..294c29948 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -1,6 +1,7 @@ const extend = require('xtend') const actions = require('../actions') const MetamascaraPlatform = require('../../../app/scripts/platforms/window') +const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums module.exports = reduceMetamask @@ -39,6 +40,7 @@ function reduceMetamask (state, action) { coinOptions: {}, useBlockie: false, featureFlags: {}, + networkEndpointType: OLD_UI_NETWORK_TYPE, }, state.metamask) switch (action.type) { @@ -335,6 +337,11 @@ function reduceMetamask (state, action) { featureFlags: action.value, }) + case actions.UPDATE_NETWORK_ENDPOINT_TYPE: + return extend(metamaskState, { + networkEndpointType: action.value, + }) + default: return metamaskState diff --git a/ui/app/select-app.js b/ui/app/select-app.js index 0b837b547..ac6867aeb 100644 --- a/ui/app/select-app.js +++ b/ui/app/select-app.js @@ -5,7 +5,8 @@ const h = require('react-hyperscript') const App = require('./app') const OldApp = require('../../old-ui/app/app') const { autoAddToBetaUI } = require('./selectors') -const { setFeatureFlag } = require('./actions') +const { setFeatureFlag, setNetworkEndpoints } = require('./actions') +const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums function mapStateToProps (state) { return { @@ -19,8 +20,14 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - setFeatureFlagWithModal: () => dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')), - setFeatureFlagWithoutModal: () => dispatch(setFeatureFlag('betaUI', true)), + setFeatureFlagWithModal: () => { + return dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) + .then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE))) + }, + setFeatureFlagWithoutModal: () => { + return dispatch(setFeatureFlag('betaUI', true)) + .then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE))) + }, } } module.exports = connect(mapStateToProps, mapDispatchToProps)(SelectedApp) diff --git a/ui/app/settings.js b/ui/app/settings.js index 74b282a98..a3dd65f14 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -9,6 +9,7 @@ const { exportAsFile } = require('./util') const TabBar = require('./components/tab-bar') const SimpleDropdown = require('./components/dropdowns/simple-dropdown') const ToggleButton = require('react-toggle-button') +const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums const getInfuraCurrencyOptions = () => { const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => { @@ -228,7 +229,7 @@ class Settings extends Component { ]) ) } - + renderOldUI () { const { setFeatureFlagToBeta } = this.props @@ -265,7 +266,7 @@ class Settings extends Component { ]) ) } - + renderLogo () { return ( h('div.settings__info-logo-wrapper', [ @@ -405,7 +406,10 @@ const mapDispatchToProps = dispatch => { displayWarning: warning => dispatch(actions.displayWarning(warning)), revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()), setUseBlockie: value => dispatch(actions.setUseBlockie(value)), - setFeatureFlagToBeta: () => dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')), + setFeatureFlagToBeta: () => { + return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) + .then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))) + }, } } diff --git a/ui/index.js b/ui/index.js index 2aa30d3fe..bc3676c1f 100644 --- a/ui/index.js +++ b/ui/index.js @@ -4,6 +4,8 @@ const Root = require('./app/root') const actions = require('./app/actions') const configureStore = require('./app/store') const txHelper = require('./lib/tx-helper') +const { OLD_UI_NETWORK_TYPE, BETA_UI_NETWORK_TYPE } = require('../app/scripts/config').enums + global.log = require('loglevel') module.exports = launchMetamaskUi @@ -35,6 +37,10 @@ function startApp (metamaskState, accountManager, opts) { networkVersion: opts.networkVersion, }) + const useBetaUi = metamaskState.featureFlags.betaUI + const networkEndpointType = useBetaUi ? BETA_UI_NETWORK_TYPE : OLD_UI_NETWORK_TYPE + store.dispatch(actions.setNetworkEndpoints(networkEndpointType)) + // if unconfirmed txs, start on txConf page const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network) const numberOfUnapprivedTx = unapprovedTxsAll.length -- cgit From 3e562f1a1e594955f203b75a0be595e4bd6bca76 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 27 Dec 2017 17:31:38 -0800 Subject: Add backend fix for util in normalizeethstringtowei. --- ui/app/util.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ui') diff --git a/ui/app/util.js b/ui/app/util.js index 3f8b4dcc3..293f4228c 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -193,6 +193,9 @@ function normalizeEthStringToWei (str) { while (decimal.length < 18) { decimal += '0' } + if (decimal.length > 18) { + decimal = decimal.slice(0, 18) + } const decimalBN = new ethUtil.BN(decimal, 10) eth = eth.add(decimalBN) } -- cgit From 92eb16fc112eeac749c0ddfff163773ce3a35ef2 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 27 Dec 2017 17:36:56 -0800 Subject: Add frontend validation to check if send ether input is a valid number. --- ui/app/send.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui') diff --git a/ui/app/send.js b/ui/app/send.js index e59c1130e..7b31eef7e 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -247,6 +247,12 @@ SendTransactionScreen.prototype.onSubmit = function () { const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '') const nickname = state.nickname || ' ' const input = document.querySelector('input[name="amount"]').value + + if (isNaN(input)) { + message = 'Invalid ether value.' + return this.props.dispatch(actions.displayWarning(message)) + } + const value = util.normalizeEthStringToWei(input) const txData = document.querySelector('input[name="txData"]').value const balance = this.props.balance -- cgit From e682fb05fcdeca5f50a2176934d25935e13538f6 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 27 Dec 2017 18:22:10 -0800 Subject: Add frontend validation to ensure that ether inputs are valid. --- ui/app/send.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/send.js b/ui/app/send.js index 7b31eef7e..09c9e03d4 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -247,16 +247,26 @@ SendTransactionScreen.prototype.onSubmit = function () { const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '') const nickname = state.nickname || ' ' const input = document.querySelector('input[name="amount"]').value + const parts = input.split('') - if (isNaN(input)) { + let message + + if (isNaN(input) || input === '') { message = 'Invalid ether value.' return this.props.dispatch(actions.displayWarning(message)) } + if (parts[1]) { + var decimal = parts[1] + if (decimal.length > 18) { + message = 'Ether amount is too precise.' + return this.props.dispatch(actions.displayWarning(message)) + } + } + const value = util.normalizeEthStringToWei(input) const txData = document.querySelector('input[name="txData"]').value const balance = this.props.balance - let message if (value.gt(balance)) { message = 'Insufficient funds.' -- cgit From 4a598fc7ac59ccf4c6cc0290956bb4985fafa8a5 Mon Sep 17 00:00:00 2001 From: Renier Oosthuizen Date: Tue, 2 Jan 2018 21:07:48 +0200 Subject: Fixes #2834 --- ui/app/app.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/app/app.js b/ui/app/app.js index bd0ccb0a2..2a2438d97 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -460,11 +460,6 @@ App.prototype.renderPrimary = function () { }) } - if (props.seedWords) { - log.debug('rendering seed words') - return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'}) - } - // show initialize screen if (!props.isInitialized || props.forgottenPassword) { // show current view @@ -499,6 +494,12 @@ App.prototype.renderPrimary = function () { } } + //Show seed words screen + if (props.seedWords) { + log.debug('rendering seed words') + return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'}) + } + // show current view switch (props.currentView.name) { -- cgit From 1da385f78b9e61e7a17c19164558779a37376868 Mon Sep 17 00:00:00 2001 From: oosthuizenr Date: Tue, 2 Jan 2018 21:29:26 +0200 Subject: fix comment --- ui/app/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/app.js b/ui/app/app.js index 2a2438d97..bc198b482 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -494,7 +494,7 @@ App.prototype.renderPrimary = function () { } } - //Show seed words screen + // show seed words screen if (props.seedWords) { log.debug('rendering seed words') return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'}) -- cgit From 20aa135ad87231694ead2fe65a3124b719b8fc4d Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 3 Jan 2018 16:06:46 -0800 Subject: Add fix for infinite spinner for incorrect seed phrase. --- ui/app/keychains/hd/restore-vault.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ui') diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js index 06e51d9b3..24b37a83d 100644 --- a/ui/app/keychains/hd/restore-vault.js +++ b/ui/app/keychains/hd/restore-vault.js @@ -149,4 +149,8 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () { this.warning = null this.props.dispatch(actions.displayWarning(this.warning)) this.props.dispatch(actions.createNewVaultAndRestore(password, seed)) + .catch((err) => { + log.error(err.message) + }) + } -- cgit From 5312ed9a20d06339c98a9e488cdede405f3c9c49 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Thu, 4 Jan 2018 17:10:40 +0300 Subject: info.js Remove width element to fix email layout --- ui/app/info.js | 1 - 1 file changed, 1 deletion(-) (limited to 'ui') diff --git a/ui/app/info.js b/ui/app/info.js index 24c211c1f..110678a46 100644 --- a/ui/app/info.js +++ b/ui/app/info.js @@ -138,7 +138,6 @@ InfoScreen.prototype.render = function () { h('div.fa.fa-envelope', [ h('a.info', { target: '_blank', - style: { width: '85vw' }, href: 'mailto:help@metamask.io?subject=Feedback', }, 'Email us!'), ]), -- cgit From ade1c404bdf26bd299bc54f83b82ad3906451eab Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 8 Jan 2018 09:44:11 -0800 Subject: ui - fix font path name --- ui/app/css/itcss/settings/typography.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/css/itcss/settings/typography.scss b/ui/app/css/itcss/settings/typography.scss index 58e2d444e..ac8c41336 100644 --- a/ui/app/css/itcss/settings/typography.scss +++ b/ui/app/css/itcss/settings/typography.scss @@ -51,14 +51,14 @@ @font-face { font-family: 'DIN NEXT'; - src: url('/fonts/DIN NEXT/DIN NEXT W01 Regular.otf') format('opentype'); + src: url('/fonts/DIN Next/DIN Next W01 Regular.otf') format('opentype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'DIN NEXT Light'; - src: url('/fonts/DIN NEXT/DIN NEXT W10 Light.otf') format('opentype'); + src: url('/fonts/DIN Next/DIN Next W10 Light.otf') format('opentype'); font-weight: 400; font-style: normal; } -- cgit From e5b34b3d044e8c414b2a390c302dd01ce6ed45e4 Mon Sep 17 00:00:00 2001 From: Dan Finlay <542863+danfinlay@users.noreply.github.com> Date: Tue, 9 Jan 2018 14:09:29 -0800 Subject: Update support links for helpscout --- ui/app/info.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/info.js b/ui/app/info.js index 110678a46..2e59db890 100644 --- a/ui/app/info.js +++ b/ui/app/info.js @@ -103,9 +103,9 @@ InfoScreen.prototype.render = function () { [ h('div.fa.fa-support', [ h('a.info', { - href: 'https://support.metamask.io', + href: 'http://metamask.helpscoutdocs.com/', target: '_blank', - }, 'Visit our Support Center'), + }, 'Visit our Knowledge Base'), ]), h('div', [ @@ -138,7 +138,7 @@ InfoScreen.prototype.render = function () { h('div.fa.fa-envelope', [ h('a.info', { target: '_blank', - href: 'mailto:help@metamask.io?subject=Feedback', + href: 'mailto:support@metamask.io?subject=MetaMask Support', }, 'Email us!'), ]), ]), -- cgit From 208e94d3bfdaf5ab6f279fb2000f1a3d14920b1b Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 10 Jan 2018 21:09:09 -0800 Subject: Update main view styling --- ui/app/app.js | 14 +++-------- ui/app/components/balance-component.js | 2 +- ui/app/components/token-cell.js | 2 +- ui/app/components/tx-view.js | 14 +++-------- ui/app/css/itcss/components/header.scss | 8 +++--- ui/app/css/itcss/components/hero-balance.scss | 30 ++++++++++++++--------- ui/app/css/itcss/components/newui-sections.scss | 29 +++++++++++----------- ui/app/css/itcss/components/token-list.scss | 6 +++-- ui/app/css/itcss/components/transaction-list.scss | 6 +---- ui/app/css/itcss/components/wallet-balance.scss | 20 +++++++++------ ui/app/css/itcss/settings/variables.scss | 1 + 11 files changed, 64 insertions(+), 68 deletions(-) (limited to 'ui') diff --git a/ui/app/app.js b/ui/app/app.js index c6fce0e47..73e5c06db 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -253,19 +253,13 @@ App.prototype.renderAppBar = function () { }, [ // mini logo h('img.metafox-icon', { - height: 29, - width: 29, - src: '/images/icon-128.png', + height: 42, + width: 42, + src: '/images/metamask-fox.svg', }), // metamask name - h('h1', { - style: { - position: 'relative', - paddingLeft: '9px', - color: '#5B5D67', - }, - }, 'MetaMask'), + h('h1', 'MetaMask'), ]), diff --git a/ui/app/components/balance-component.js b/ui/app/components/balance-component.js index 50007ce14..d591ab455 100644 --- a/ui/app/components/balance-component.js +++ b/ui/app/components/balance-component.js @@ -40,7 +40,7 @@ BalanceComponent.prototype.render = function () { // style: {}, // }), h(Identicon, { - diameter: 45, + diameter: 50, address: token && token.address, network, }), diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js index 677b66830..59552f4a0 100644 --- a/ui/app/components/token-cell.js +++ b/ui/app/components/token-cell.js @@ -106,7 +106,7 @@ TokenCell.prototype.render = function () { h(Identicon, { className: 'token-list-item__identicon', - diameter: 45, + diameter: 50, address, network, }), diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js index e42a20c85..7bddbbef4 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -68,18 +68,14 @@ TxView.prototype.renderButtons = function () { return !selectedToken ? ( h('div.flex-row.flex-center.hero-balance-buttons', [ - h('button.btn-clear', { - style: { - textAlign: 'center', - }, + h('button.hero-balance-button', { onClick: () => showModal({ name: 'BUY', }), }, 'DEPOSIT'), - h('button.btn-clear', { + h('button.hero-balance-button', { style: { - textAlign: 'center', marginLeft: '0.8em', }, onClick: showSendPage, @@ -88,11 +84,7 @@ TxView.prototype.renderButtons = function () { ) : ( h('div.flex-row.flex-center.hero-balance-buttons', [ - h('button.btn-clear', { - style: { - textAlign: 'center', - marginLeft: '0.8em', - }, + h('button.hero-balance-button', { onClick: showSendTokenPage, }, 'SEND'), ]) diff --git a/ui/app/css/itcss/components/header.scss b/ui/app/css/itcss/components/header.scss index a6332f819..2a1f7abc7 100644 --- a/ui/app/css/itcss/components/header.scss +++ b/ui/app/css/itcss/components/header.scss @@ -53,7 +53,7 @@ } @media screen and (min-width: 1281px) { - width: 65vw; + width: 62vw; } } @@ -61,8 +61,10 @@ font-family: Roboto; text-transform: uppercase; font-weight: 400; - color: #22232c; // $shark - line-height: 29px; + font-size: 1.1rem; + position: relative; + padding-left: 15px; + color: #5b5d67; @media screen and (max-width: 575px) { display: none; diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss index bdbdd2645..643363f95 100644 --- a/ui/app/css/itcss/components/hero-balance.scss +++ b/ui/app/css/itcss/components/hero-balance.scss @@ -16,7 +16,7 @@ flex-direction: row; justify-content: flex-start; align-items: center; - margin: 2.8em 2.37em .8em; + margin: 2.3em 2.37em .8em; } .balance-container { @@ -42,8 +42,9 @@ text-align: center; .token-amount { - font-size: 175%; - margin-top: 12.5%; + font-size: 1.75rem; + margin-top: 1rem; + font-weight: 400; } .fiat-amount { @@ -54,12 +55,13 @@ } @media screen and (min-width: $break-large) { - margin-left: 3%; + margin-left: .8em; justify-content: flex-start; align-items: flex-start; .token-amount { - font-size: 135%; + font-size: 1.5rem; + font-weight: 400; } .fiat-amount { @@ -69,13 +71,6 @@ } } - .balance-icon { - border-radius: 25px; - width: 45px; - height: 45px; - border: 1px solid $alto; - } - .hero-balance-buttons { @media screen and (max-width: $break-small) { @@ -112,3 +107,14 @@ } } } + +.hero-balance-button { + text-align: center; + padding: .9rem 1rem; + color: $white; + background: $curious-blue; + border-radius: 2px; + font-size: .85rem; + width: 6rem; + font-weight: 300; +} diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index 61dfbd176..3ae47cb35 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -4,7 +4,7 @@ // Component Colors $tx-view-bg: $white; -$wallet-view-bg: $wild-sand; +$wallet-view-bg: $alabaster; // Main container .main-container { @@ -47,7 +47,7 @@ $wallet-view-bg: $wild-sand; .wallet-view { display: flex; flex-direction: column; - flex: 33.5 1 33.5%; + flex: 32 1 32%; width: 0; background: $wallet-view-bg; z-index: 200; @@ -69,22 +69,21 @@ $wallet-view-bg: $wild-sand; } &__keyring-label { - height: 40px; + height: 50px; color: $dusty-gray; font-family: Roboto; font-size: 10px; - line-height: 40px; text-align: right; - padding: 0 20px; + padding: 17px 20px 0; + box-sizing: border-box; } &__details-button { color: $curious-blue; font-size: 10px; - line-height: 13px; text-align: center; border: 1px solid $curious-blue; - border-radius: 10.5px; + border-radius: 17px; background-color: transparent; margin: 0 auto; padding: 4px 12px; @@ -121,12 +120,12 @@ $wallet-view-bg: $wild-sand; &__add-token-button { flex: 0 0 auto; - color: $dusty-gray; + color: $curious-blue; font-size: 14px; line-height: 19px; text-align: center; margin: 36px auto; - border: 1px solid $dusty-gray; + border: 1px solid $curious-blue; border-radius: 2px; font-weight: 300; background: none; @@ -199,7 +198,7 @@ $wallet-view-bg: $wild-sand; .main-container { // margin-top: 6.9vh; - width: 85%; + width: 85vw; height: 90vh; box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08); } @@ -208,7 +207,7 @@ $wallet-view-bg: $wild-sand; @media screen and (min-width: 769px) { .main-container { // margin-top: 6.9vh; - width: 80%; + width: 80vw; height: 82vh; box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08); } @@ -217,7 +216,7 @@ $wallet-view-bg: $wild-sand; @media screen and (min-width: 1281px) { .main-container { // margin-top: 6.9vh; - width: 65%; + width: 62vw; height: 82vh; box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08); } @@ -252,11 +251,11 @@ $wallet-view-bg: $wild-sand; // wallet view .account-name { font-size: 24px; - font-weight: 300; + font-weight: 400; line-height: 20px; - color: $scorpion; + color: $black; margin-top: 8px; - margin-bottom: 24px; + margin-bottom: .9rem; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index d4add71b1..5cd5b3807 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -12,7 +12,8 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( position: relative; &__token-balance { - font-size: 130%; + font-size: 1.5rem; + font-weight: 400; @media #{$wallet-balance-breakpoint-range} { font-size: 105%; @@ -34,7 +35,8 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( } &--active { - background-color: rgba($wallet-balance-bg, 1); + background-color: $manatee; + color: $white; } &__identicon { diff --git a/ui/app/css/itcss/components/transaction-list.scss b/ui/app/css/itcss/components/transaction-list.scss index a5d508f11..0ff0b3dda 100644 --- a/ui/app/css/itcss/components/transaction-list.scss +++ b/ui/app/css/itcss/components/transaction-list.scss @@ -32,13 +32,9 @@ } @media screen and (min-width: $break-large) { - .tx-list-header-wrapper { - flex: 0 0 55px; - } - .tx-list-header { font-size: 16px; - margin: 1.5em 2.37em; + margin: 1.1em 2.37em .8em; } .tx-list-container::-webkit-scrollbar { diff --git a/ui/app/css/itcss/components/wallet-balance.scss b/ui/app/css/itcss/components/wallet-balance.scss index 64b291b89..44f405e08 100644 --- a/ui/app/css/itcss/components/wallet-balance.scss +++ b/ui/app/css/itcss/components/wallet-balance.scss @@ -8,7 +8,8 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( background: rgba($wallet-balance-bg, 0); &--active { - background: rgba($wallet-balance-bg, 1); + background: $manatee; + color: $white; } } @@ -41,7 +42,8 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( align-items: flex-start; .token-amount { - font-size: 135%; + font-size: 1.5rem; + font-weight: 400; } .fiat-amount { @@ -61,11 +63,13 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( } } } +} - .balance-icon { - border-radius: 25px; - width: 45px; - height: 45px; - border: 1px solid $alto; - } +.balance-icon { + border-radius: 25px; + width: 50px; + height: 50px; + border: 1px solid $alto; + padding: 5px; + background: $white; } diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index 387d14b5f..7e723966b 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -42,6 +42,7 @@ $malibu-blue: #7ac9fd; $athens-grey: #e9edf0; $jaffa: #f28930; $geyser: #d2d8dd; +$manatee: #93949d; /* Z-Indicies -- cgit From 60a52b260863e62b1717581e0fa6fb8dd91e1234 Mon Sep 17 00:00:00 2001 From: tmashuang Date: Wed, 10 Jan 2018 21:54:43 -0800 Subject: Add one px to address for Firefox clipping --- ui/app/account-detail.js | 1 + 1 file changed, 1 insertion(+) (limited to 'ui') diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js index d4f707e0b..c9a8a774d 100644 --- a/ui/app/account-detail.js +++ b/ui/app/account-detail.js @@ -161,6 +161,7 @@ AccountDetailScreen.prototype.render = function () { textOverflow: 'ellipsis', paddingTop: '3px', width: '5em', + height: '15px', fontSize: '13px', fontFamily: 'Montserrat Light', textRendering: 'geometricPrecision', -- cgit From be604391d0b3bbd3a2cae3aef79889130850f472 Mon Sep 17 00:00:00 2001 From: tmashuang Date: Wed, 10 Jan 2018 21:56:07 -0800 Subject: Add max height for Firefox addon overflow and hide horizontal scroll --- ui/app/css/index.css | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ui') diff --git a/ui/app/css/index.css b/ui/app/css/index.css index c0bf18c23..b40d48b5d 100644 --- a/ui/app/css/index.css +++ b/ui/app/css/index.css @@ -441,7 +441,9 @@ input.large-input { .account-detail-section { display: flex; flex-wrap: wrap; + overflow-x: hidden; overflow-y: auto; + max-height: 465px; flex-direction: inherit; } -- cgit From 7c97b2f37c0226daef734bae3392b6ade2b2956f Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 11 Jan 2018 13:51:41 -0330 Subject: Fix padding of a hovered tx-list-item (#2859) --- ui/app/css/itcss/components/transaction-list.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/css/itcss/components/transaction-list.scss b/ui/app/css/itcss/components/transaction-list.scss index a5d508f11..fb09fd800 100644 --- a/ui/app/css/itcss/components/transaction-list.scss +++ b/ui/app/css/itcss/components/transaction-list.scss @@ -210,7 +210,7 @@ } @media screen and (min-width: $break-large) { - margin: 0 2.37em; + padding: 0 2.37em; } &:last-of-type { -- cgit From b8310ac62e358af9a6a9f3ed1e0ffa25a2a00b8d Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 11 Jan 2018 15:49:10 -0800 Subject: Fix logging out of old UI causing infinite spinner (#2914) --- ui/app/actions.js | 6 +++++- ui/app/components/account-menu/index.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index bd3aab45a..55773b3b5 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -925,9 +925,13 @@ function lockMetamask () { }) .then(newState => { dispatch(actions.updateMetamaskState(newState)) + dispatch(actions.hideLoadingIndication()) + dispatch({ type: actions.LOCK_METAMASK }) + }) + .catch(() => { + dispatch(actions.hideLoadingIndication()) dispatch({ type: actions.LOCK_METAMASK }) }) - .catch(() => dispatch({ type: actions.LOCK_METAMASK })) } } diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index 286a3b587..1b62b42fb 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -33,7 +33,7 @@ function mapDispatchToProps (dispatch) { }, lockMetamask: () => { dispatch(actions.lockMetamask()) - dispatch(actions.displayWarning(null)) + dispatch(actions.hideWarning()) dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, -- cgit From 376e1365727a97344d70d627ae27e8e70830a17a Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 11 Jan 2018 16:30:07 -0800 Subject: Update styling for buttons, font weights --- ui/app/components/modals/account-details-modal.js | 4 +-- .../components/modals/export-private-key-modal.js | 10 ++++-- ui/app/components/pending-tx/confirm-send-ether.js | 4 +-- ui/app/components/pending-tx/confirm-send-token.js | 4 +-- ui/app/components/tx-view.js | 6 ++-- ui/app/components/wallet-view.js | 4 +-- ui/app/css/itcss/components/buttons.scss | 38 ++++++++++++++++++++-- ui/app/css/itcss/components/confirm.scss | 9 ++--- ui/app/css/itcss/components/hero-balance.scss | 31 +----------------- ui/app/css/itcss/components/modal.scss | 29 ++++++----------- ui/app/css/itcss/components/newui-sections.scss | 27 ++++----------- ui/app/css/itcss/components/send.scss | 34 +++---------------- ui/app/css/itcss/components/token-list.scss | 1 - ui/app/css/itcss/components/wallet-balance.scss | 1 - ui/app/css/itcss/settings/variables.scss | 1 + ui/app/send-v2.js | 5 +-- 16 files changed, 83 insertions(+), 125 deletions(-) (limited to 'ui') diff --git a/ui/app/components/modals/account-details-modal.js b/ui/app/components/modals/account-details-modal.js index 4bf671834..c1f7a3236 100644 --- a/ui/app/components/modals/account-details-modal.js +++ b/ui/app/components/modals/account-details-modal.js @@ -62,12 +62,12 @@ AccountDetailsModal.prototype.render = function () { h('div.account-modal-divider'), - h('button.btn-clear', { + h('button.btn-clear.account-modal__button', { onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }), }, 'View account on Etherscan'), // Holding on redesign for Export Private Key functionality - h('button.btn-clear', { + h('button.btn-clear.account-modal__button', { onClick: () => showExportPrivateKeyModal(), }, 'Export private key'), diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js index 193755df5..422f23f44 100644 --- a/ui/app/components/modals/export-private-key-modal.js +++ b/ui/app/components/modals/export-private-key-modal.js @@ -79,11 +79,15 @@ ExportPrivateKeyModal.prototype.renderButton = function (className, onClick, lab ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) { return h('div.export-private-key-buttons', {}, [ - !privateKey && this.renderButton('btn-clear btn-cancel', () => hideModal(), 'Cancel'), + !privateKey && this.renderButton( + 'btn-cancel export-private-key__button export-private-key__button--cancel', + () => hideModal(), + 'Cancel' + ), (privateKey - ? this.renderButton('btn-clear', () => hideModal(), 'Done') - : this.renderButton('btn-clear', () => this.exportAccountAndGetPrivateKey(this.state.password, address), 'Show') + ? this.renderButton('btn-clear export-private-key__button', () => hideModal(), 'Done') + : this.renderButton('btn-clear export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), 'Confirm') ), ]) diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 566224864..652300c94 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -219,7 +219,7 @@ ConfirmSendEther.prototype.render = function () { // Main Send token Card h('div.confirm-screen-wrapper.flex-column.flex-grow', [ h('h3.flex-center.confirm-screen-header', [ - h('button.confirm-screen-back-button', { + h('button.btn-clear.confirm-screen-back-button', { onClick: () => editTransaction(txMeta), }, 'EDIT'), h('div.confirm-screen-title', 'Confirm Transaction'), @@ -422,7 +422,7 @@ ConfirmSendEther.prototype.onSubmit = function (event) { ConfirmSendEther.prototype.cancel = function (event, txMeta) { event.preventDefault() const { cancelTransaction } = this.props - + cancelTransaction(txMeta) } diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index aa4f29fb0..ad489c3e9 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -314,7 +314,7 @@ ConfirmSendToken.prototype.render = function () { // Main Send token Card h('div.confirm-screen-wrapper.flex-column.flex-grow', [ h('h3.flex-center.confirm-screen-header', [ - h('button.confirm-screen-back-button', { + h('button.btn-clear.confirm-screen-back-button', { onClick: () => editTransaction(txMeta), }, 'EDIT'), h('div.confirm-screen-title', 'Confirm Transaction'), @@ -415,7 +415,7 @@ ConfirmSendToken.prototype.onSubmit = function (event) { ConfirmSendToken.prototype.cancel = function (event, txMeta) { event.preventDefault() const { cancelTransaction } = this.props - + cancelTransaction(txMeta) } diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js index 7bddbbef4..72183f0f7 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -68,13 +68,13 @@ TxView.prototype.renderButtons = function () { return !selectedToken ? ( h('div.flex-row.flex-center.hero-balance-buttons', [ - h('button.hero-balance-button', { + h('button.btn-clear.hero-balance-button', { onClick: () => showModal({ name: 'BUY', }), }, 'DEPOSIT'), - h('button.hero-balance-button', { + h('button.btn-clear.hero-balance-button', { style: { marginLeft: '0.8em', }, @@ -84,7 +84,7 @@ TxView.prototype.renderButtons = function () { ) : ( h('div.flex-row.flex-center.hero-balance-buttons', [ - h('button.hero-balance-button', { + h('button.btn-clear.hero-balance-button', { onClick: showSendTokenPage, }, 'SEND'), ]) diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index 3cb7a8b76..b1ef83cee 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -130,7 +130,7 @@ WalletView.prototype.render = function () { selectedIdentity.name, ]), - h('button.wallet-view__details-button', 'DETAILS'), + h('button.btn-clear.wallet-view__details-button', 'DETAILS'), ]), ]), @@ -151,7 +151,7 @@ WalletView.prototype.render = function () { h(TokenList), - h('button.wallet-view__add-token-button', { + h('button.btn-clear.wallet-view__add-token-button', { onClick: () => { showAddTokenPage() hideSidebar() diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss index 8ba084b4a..1450b71cc 100644 --- a/ui/app/css/itcss/components/buttons.scss +++ b/ui/app/css/itcss/components/buttons.scss @@ -6,9 +6,43 @@ background-color: #02c9b1; // TODO: reusable color in colors.css } -button.btn-clear { +.btn-clear { background: $white; - border: 1px solid; + text-align: center; + padding: .8rem 1rem; + color: $curious-blue; + border: 2px solid $spindle; + border-radius: 4px; + font-size: .85rem; + font-weight: 400; + transition: border-color .3s ease; + + &:hover { + border-color: $curious-blue; + } + + &--disabled, + &[disabled] { + cursor: auto; + opacity: .5; + pointer-events: none; + } +} + +.btn-cancel { + background: $white; + text-align: center; + padding: .9rem 1rem; + color: $scorpion; + border: 2px solid $dusty-gray; + border-radius: 4px; + font-size: .85rem; + font-weight: 400; + transition: border-color .3s ease; + + &:hover { + border-color: $scorpion; + } } // No longer used in flat design, remove when modal buttons done diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss index 4a8232e39..e75a827f9 100644 --- a/ui/app/css/itcss/components/confirm.scss +++ b/ui/app/css/itcss/components/confirm.scss @@ -102,15 +102,10 @@ .confirm-screen-back-button { background: transparent; - border: 1px solid $curious-blue; left: 24px; position: absolute; - text-align: center; - color: $curious-blue; - padding: 6px 13px 7px 12px; - border-radius: 2px; - height: 30px; - width: 54px; + padding: 6px 12px; + font-size: .7rem; @media screen and (max-width: $break-small) { margin-right: 12px; diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss index 643363f95..a7a883909 100644 --- a/ui/app/css/itcss/components/hero-balance.scss +++ b/ui/app/css/itcss/components/hero-balance.scss @@ -37,6 +37,7 @@ } .balance-display { + color: $black; @media screen and (max-width: $break-small) { text-align: center; @@ -44,7 +45,6 @@ .token-amount { font-size: 1.75rem; margin-top: 1rem; - font-weight: 400; } .fiat-amount { @@ -61,7 +61,6 @@ .token-amount { font-size: 1.5rem; - font-weight: 400; } .fiat-amount { @@ -84,37 +83,9 @@ flex-grow: 2; justify-content: flex-end; } - - button.btn-clear { - background: $white; - border: 1px solid; - border-radius: 2px; - font-size: 12px; - - @media screen and (max-width: $break-small) { - border-color: $curious-blue; - color: $curious-blue; - height: 36px; - } - - @media screen and (min-width: $break-large) { - border-color: $curious-blue; - color: $curious-blue; - padding: 0; - width: 85px; - height: 34px; - } - } } } .hero-balance-button { - text-align: center; - padding: .9rem 1rem; - color: $white; - background: $curious-blue; - border-radius: 2px; - font-size: .85rem; width: 6rem; - font-weight: 300; } diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss index 9b64564d6..307401666 100644 --- a/ui/app/css/itcss/components/modal.scss +++ b/ui/app/css/itcss/components/modal.scss @@ -258,19 +258,10 @@ width: 286px; } - .btn-clear { - min-height: 28px; - font-size: 14px; - border-color: $curious-blue; - color: $curious-blue; - border-radius: 2px; - flex-basis: 100%; - width: 75%; + .account-modal__button { margin-top: 17px; padding: 10px 22px; - height: 44px; width: 235px; - font-family: Roboto; } } @@ -346,17 +337,17 @@ display: flex; flex-direction: row; justify-content: center; +} - .btn-clear { - width: 141px; - height: 54px; - } +.export-private-key__button { + margin-top: 17px; + padding: 10px 22px; + width: 141px; + height: 54px; +} - .btn-cancel { - margin-right: 15px; - border-color: $dusty-gray; - color: $scorpion; - } +.export-private-key__button--cancel { + margin-right: 15px; } .private-key-password-display-wrapper { diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index 3ae47cb35..af1a6974c 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -79,10 +79,7 @@ $wallet-view-bg: $alabaster; } &__details-button { - color: $curious-blue; font-size: 10px; - text-align: center; - border: 1px solid $curious-blue; border-radius: 17px; background-color: transparent; margin: 0 auto; @@ -120,16 +117,14 @@ $wallet-view-bg: $alabaster; &__add-token-button { flex: 0 0 auto; - color: $curious-blue; - font-size: 14px; - line-height: 19px; - text-align: center; margin: 36px auto; - border: 1px solid $curious-blue; - border-radius: 2px; - font-weight: 300; background: none; - padding: 9px 30px; + padding: .7rem 2rem; + transition: border-color .3s ease; + + &:hover { + border-color: $curious-blue; + } } } @@ -238,20 +233,12 @@ $wallet-view-bg: $alabaster; overflow-y: auto; background-color: $white; } - - button.btn-clear { - width: 93px; - height: 50px; - font-size: .7em; - background: $white; - border: 1px solid; - } } // wallet view .account-name { font-size: 24px; - font-weight: 400; + font-weight: 300; line-height: 20px; color: $black; margin-top: 8px; diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index 2bd192788..beb3e519c 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -526,8 +526,9 @@ } &__form { - margin: 13px 0; + padding: 13px 0; width: 100%; + overflow-y: auto; @media screen and (max-width: $break-small) { padding: 13px 0; @@ -587,7 +588,7 @@ width: 100%; height: 100%; } - + &__list { z-index: 1050; position: absolute; @@ -677,40 +678,15 @@ border-top: 1px solid $alto; background: $white; padding: 0 12px; + flex-shrink: 0; } &__next-btn, - &__cancel-btn, - &__next-btn__disabled { + &__cancel-btn { width: 163px; - text-align: center; - height: 55px; - border-radius: 2px; - background-color: $white; - font-family: Roboto; - font-size: 16px; - font-weight: 300; - line-height: 21px; - border: 1px solid; margin: 0 4px; } - &__next-btn, - &__next-btn__disabled { - color: $curious-blue; - border-color: $curious-blue; - } - - &__next-btn__disabled { - opacity: .5; - cursor: auto; - } - - &__cancel-btn { - color: $dusty-gray; - border-color: $dusty-gray; - } - &__customize-gas { border: 1px solid #D8D8D8; border-radius: 4px; diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index 5cd5b3807..bdd26099a 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -13,7 +13,6 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( &__token-balance { font-size: 1.5rem; - font-weight: 400; @media #{$wallet-balance-breakpoint-range} { font-size: 105%; diff --git a/ui/app/css/itcss/components/wallet-balance.scss b/ui/app/css/itcss/components/wallet-balance.scss index 44f405e08..293771550 100644 --- a/ui/app/css/itcss/components/wallet-balance.scss +++ b/ui/app/css/itcss/components/wallet-balance.scss @@ -43,7 +43,6 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( .token-amount { font-size: 1.5rem; - font-weight: 400; } .fiat-amount { diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index 7e723966b..8bd1ad20d 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -43,6 +43,7 @@ $athens-grey: #e9edf0; $jaffa: #f28930; $geyser: #d2d8dd; $manatee: #93949d; +$spindle: #c7ddec; /* Z-Indicies diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 7c9b6dbc6..cc6635e82 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -519,13 +519,14 @@ SendTransactionScreen.prototype.renderFooter = function () { const errorClass = noErrors ? '' : '__disabled' return h('div.send-v2__footer', [ - h('button.send-v2__cancel-btn', { + h('button.btn-cancel.send-v2__cancel-btn', { onClick: () => { clearSend() goHome() }, }, 'Cancel'), - h(`button.send-v2__next-btn${errorClass}`, { + h('button.btn-clear.send-v2__next-btn', { + disabled: !noErrors, onClick: event => this.onSubmit(event), }, 'Next'), ]) -- cgit From b0a6bfdeece8a5afb860bc47f01373d08a0895b8 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 11 Jan 2018 16:59:00 -0800 Subject: Change styling for network dropdown --- ui/app/components/network.js | 41 ++++++++----------------------- ui/app/css/itcss/components/network.scss | 42 ++++++++++++-------------------- 2 files changed, 25 insertions(+), 58 deletions(-) (limited to 'ui') diff --git a/ui/app/components/network.js b/ui/app/components/network.js index 5a8d0763d..3f147159b 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -39,7 +39,6 @@ Network.prototype.render = function () { }, src: 'images/loading.svg', }), - h('i.fa.fa-caret-down.network-caret'), ]) } else if (providerName === 'mainnet') { hoverText = 'Main Ethereum Network' @@ -85,12 +84,8 @@ Network.prototype.render = function () { backgroundColor: '#038789', // $blue-lagoon nonSelectBackgroundColor: '#15afb2', }), - h('.network-name', { - style: { - color: '#039396', - }}, - 'Main Network'), - h('i.fa.fa-caret-down.fa-lg.network-caret'), + h('.network-name', 'Main Network'), + h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) case 'ropsten-test-network': return h('.network-indicator', [ @@ -98,12 +93,8 @@ Network.prototype.render = function () { backgroundColor: '#e91550', // $crimson nonSelectBackgroundColor: '#ec2c50', }), - h('.network-name', { - style: { - color: '#ff6666', - }}, - 'Ropsten Test Net'), - h('i.fa.fa-caret-down.fa-lg.network-caret'), + h('.network-name', 'Ropsten Test Net'), + h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) case 'kovan-test-network': return h('.network-indicator', [ @@ -111,12 +102,8 @@ Network.prototype.render = function () { backgroundColor: '#690496', // $purple nonSelectBackgroundColor: '#b039f3', }), - h('.network-name', { - style: { - color: '#690496', - }}, - 'Kovan Test Net'), - h('i.fa.fa-caret-down.fa-lg.network-caret'), + h('.network-name', 'Kovan Test Net'), + h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) case 'rinkeby-test-network': return h('.network-indicator', [ @@ -124,12 +111,8 @@ Network.prototype.render = function () { backgroundColor: '#ebb33f', // $tulip-tree nonSelectBackgroundColor: '#ecb23e', }), - h('.network-name', { - style: { - color: '#e7a218', - }}, - 'Rinkeby Test Net'), - h('i.fa.fa-caret-down.fa-lg.network-caret'), + h('.network-name', 'Rinkeby Test Net'), + h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) default: return h('.network-indicator', [ @@ -140,12 +123,8 @@ Network.prototype.render = function () { }, }), - h('.network-name', { - style: { - color: '#AEAEAE', - }}, - 'Private Network'), - h('i.fa.fa-caret-down.fa-lg.network-caret'), + h('.network-name', 'Private Network'), + h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) } })(), diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss index 98dbdffb2..d9a39b8d5 100644 --- a/ui/app/css/itcss/components/network.scss +++ b/ui/app/css/itcss/components/network.scss @@ -8,41 +8,25 @@ } .network-component.pointer { - border: 1px solid $shark; + border: 2px solid $silver; border-radius: 82px; - padding: 6px; + padding: 3px; flex: 0 0 auto; - &.ethereum-network { - border-color: rgb(3, 135, 137); - - .menu-icon-circle div { - background-color: rgba(3, 135, 137, .7) !important; - } + &.ethereum-network .menu-icon-circle div { + background-color: rgba(3, 135, 137, .7) !important; } - &.ropsten-test-network { - border-color: rgb(233, 21, 80); - - .menu-icon-circle div { - background-color: rgba(233, 21, 80, .7) !important; - } + &.ropsten-test-network .menu-icon-circle div { + background-color: rgba(233, 21, 80, .7) !important; } - &.kovan-test-network { - border-color: rgb(105, 4, 150); - - .menu-icon-circle div { - background-color: rgba(105, 4, 150, .7) !important; - } + &.kovan-test-network .menu-icon-circle div { + background-color: rgba(105, 4, 150, .7) !important; } - &.rinkeby-test-network { - border-color: rgb(235, 179, 63); - - .menu-icon-circle div { - background-color: rgba(235, 179, 63, .7) !important; - } + &.rinkeby-test-network .menu-icon-circle div { + background-color: rgba(235, 179, 63, .7) !important; } } @@ -66,11 +50,12 @@ } .network-name { - line-height: 15px; padding: 0 4px; font-family: Roboto; font-size: 12px; flex: 1 0 auto; + color: $tundora; + font-weight: 500; } .network-droppo { @@ -167,3 +152,6 @@ line-height: 18px; } +.network-caret { + margin: 0 8px 2px; +} -- cgit From b35e4e026419e42255dbeddee0fe39422fb2bce8 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 11 Jan 2018 17:06:30 -0800 Subject: Fix lint errors --- ui/app/send-v2.js | 1 - 1 file changed, 1 deletion(-) (limited to 'ui') diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index cc6635e82..ca73fa5ea 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -516,7 +516,6 @@ SendTransactionScreen.prototype.renderFooter = function () { } = this.props const noErrors = !amountError && toError === null - const errorClass = noErrors ? '' : '__disabled' return h('div.send-v2__footer', [ h('button.btn-cancel.send-v2__cancel-btn', { -- cgit From 0f4bfcb02e3a04f044a571e01a4977dae2afec8e Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 11 Jan 2018 17:12:58 -0800 Subject: Fix token balance color --- ui/app/css/itcss/components/hero-balance.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss index a7a883909..99fd2a96d 100644 --- a/ui/app/css/itcss/components/hero-balance.scss +++ b/ui/app/css/itcss/components/hero-balance.scss @@ -37,7 +37,9 @@ } .balance-display { - color: $black; + .token-amount { + color: $black; + } @media screen and (max-width: $break-small) { text-align: center; -- cgit From 429db74508cd5c0cd275d4872d9553bd29c6ea38 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 12 Jan 2018 11:03:03 -0800 Subject: Use https --- ui/app/info.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/info.js b/ui/app/info.js index 2e59db890..49ff9f24a 100644 --- a/ui/app/info.js +++ b/ui/app/info.js @@ -103,7 +103,7 @@ InfoScreen.prototype.render = function () { [ h('div.fa.fa-support', [ h('a.info', { - href: 'http://metamask.helpscoutdocs.com/', + href: 'https://metamask.helpscoutdocs.com/', target: '_blank', }, 'Visit our Knowledge Base'), ]), -- cgit From 5c1dcf3e9bdb317dd8b42aadb18657eb4bfa2e0f Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 12 Jan 2018 16:18:18 -0330 Subject: [NewUI-flat] New deposit ether modal UI. (#2642) * New deposit ether modal. * New deposit modal full screen on mobile, and other style fixes. * Hide shapeshift option from deposit modal for now. * Add shapeshift form to new deposit modal. * Store recipient address for shapeshift tx in background. * Use Simpledropdown to achieve desired styling in coin selector. * Lint fix * Fix typos and remove dead code. * Remove storage of shapeshift receiving address from background. * Fix typos --- ui/app/actions.js | 5 +- ui/app/components/modals/buy-options-modal.js | 2 +- ui/app/components/modals/deposit-ether-modal.js | 182 +++++++++ ui/app/components/modals/modal.js | 32 ++ ui/app/components/shapeshift-form.js | 468 ++++++++++-------------- ui/app/components/shift-list-item.js | 50 +-- ui/app/components/tx-list.js | 10 +- ui/app/components/tx-view.js | 2 +- ui/app/css/itcss/components/modal.scss | 254 ++++++++++++- ui/app/css/itcss/settings/variables.scss | 2 + ui/app/reducers/app.js | 5 +- 11 files changed, 711 insertions(+), 301 deletions(-) create mode 100644 ui/app/components/modals/deposit-ether-modal.js (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 55773b3b5..0d96d2b59 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1438,7 +1438,6 @@ function pairUpdate (coin) { function shapeShiftSubview (network) { var pair = 'btc_eth' - return (dispatch) => { dispatch(actions.showSubLoadingIndication()) shapeShiftRequest('marketinfo', {pair}, (mktResponse) => { @@ -1464,7 +1463,7 @@ function coinShiftRquest (data, marketData) { dispatch(actions.hideLoadingIndication()) if (response.error) return dispatch(actions.displayWarning(response.error)) var message = ` - Deposit your ${response.depositType} to the address bellow:` + Deposit your ${response.depositType} to the address below:` log.debug(`background.createShapeShiftTx`) background.createShapeShiftTx(response.deposit, response.depositType) dispatch(actions.showQrView(response.deposit, [message].concat(marketData))) @@ -1500,7 +1499,7 @@ function reshowQrCode (data, coin) { if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error)) var message = [ - `Deposit your ${coin} to the address bellow:`, + `Deposit your ${coin} to the address below:`, `Deposit Limit: ${mktResponse.limit}`, `Deposit Minimum:${mktResponse.minimum}`, ] diff --git a/ui/app/components/modals/buy-options-modal.js b/ui/app/components/modals/buy-options-modal.js index d735983f9..74a7a847e 100644 --- a/ui/app/components/modals/buy-options-modal.js +++ b/ui/app/components/modals/buy-options-modal.js @@ -69,7 +69,7 @@ BuyOptions.prototype.render = function () { // h('div.buy-modal-content-option', {}, [ // h('div.buy-modal-content-option-title', {}, 'Shapeshift'), // h('div.buy-modal-content-option-subtitle', {}, 'Trade any digital asset for any other'), - // ]), + // ]),, this.renderModalContentOption( 'Direct Deposit', diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js new file mode 100644 index 000000000..3e6d3fde1 --- /dev/null +++ b/ui/app/components/modals/deposit-ether-modal.js @@ -0,0 +1,182 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const connect = require('react-redux').connect +const actions = require('../../actions') +const networkNames = require('../../../../app/scripts/config.js').networkNames +const ShapeshiftForm = require('../shapeshift-form') + +const DIRECT_DEPOSIT_ROW_TITLE = 'Directly Deposit Ether' +const DIRECT_DEPOSIT_ROW_TEXT = `If you already have some Ether, the quickest way to get Ether in +your new wallet by direct deposit.` +const COINBASE_ROW_TITLE = 'Buy on Coinbase' +const COINBASE_ROW_TEXT = `Coinbase is the world’s most popular way to buy and sell bitcoin, +ethereum, and litecoin.` +const SHAPESHIFT_ROW_TITLE = 'Deposit with ShapeShift' +const SHAPESHIFT_ROW_TEXT = `If you own other cryptocurrencies, you can trade and deposit Ether +directly into your MetaMask wallet. No Account Needed.` +const FAUCET_ROW_TITLE = 'Test Faucet' +const facuetRowText = networkName => `Get Ether from a faucet for the ${networkName}` + +function mapStateToProps (state) { + return { + network: state.metamask.network, + address: state.metamask.selectedAddress, + } +} + +function mapDispatchToProps (dispatch) { + return { + toCoinbase: (address) => { + dispatch(actions.buyEth({ network: '1', address, amount: 0 })) + }, + hideModal: () => { + dispatch(actions.hideModal()) + }, + showAccountDetailModal: () => { + dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })) + }, + toFaucet: network => dispatch(actions.buyEth({ network })), + } +} + +inherits(DepositEtherModal, Component) +function DepositEtherModal () { + Component.call(this) + + this.state = { + buyingWithShapeshift: false, + } +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)(DepositEtherModal) + +DepositEtherModal.prototype.renderRow = function ({ + logo, + title, + text, + buttonLabel, + onButtonClick, + hide, + className, + hideButton, + hideTitle, + onBackClick, +}) { + if (hide) { + return null + } + + return h('div', { + className: className || 'deposit-ether-modal__buy-row', + }, [ + + h('div.deposit-ether-modal__buy-row__back', { + onClick: onBackClick, + }, [ + + h('i.fa.fa-arrow-left.cursor-pointer'), + + ]), + + h('div.deposit-ether-modal__buy-row__logo', [logo]), + + h('div.deposit-ether-modal__buy-row__description', [ + + !hideTitle && h('div.deposit-ether-modal__buy-row__description__title', [title]), + + h('div.deposit-ether-modal__buy-row__description__text', [text]), + + ]), + + !hideButton && h('div.deposit-ether-modal__buy-row__button', [ + h('button.deposit-ether-modal__deposit-button', { + onClick: onButtonClick, + }, [buttonLabel]), + ]), + + ]) +} + +DepositEtherModal.prototype.render = function () { + const { network, toCoinbase, address, toFaucet } = this.props + const { buyingWithShapeshift } = this.state + + const isTestNetwork = ['3', '4', '42'].find(n => n === network) + const networkName = networkNames[network] + + return h('div.deposit-ether-modal', {}, [ + + h('div.deposit-ether-modal__header', [ + + h('div.deposit-ether-modal__header__title', ['Deposit Ether']), + + h('div.deposit-ether-modal__header__description', [ + 'To interact with decentralized applications using MetaMask, you’ll need Ether in your wallet.', + ]), + + h('div.deposit-ether-modal__header__close', { + onClick: () => { + this.setState({ buyingWithShapeshift: false }) + this.props.hideModal() + }, + }), + + ]), + + h('div.deposit-ether-modal__buy-rows', [ + + this.renderRow({ + logo: h('img.deposit-ether-modal__buy-row__eth-logo', { src: '../../../images/eth_logo.svg' }), + title: DIRECT_DEPOSIT_ROW_TITLE, + text: DIRECT_DEPOSIT_ROW_TEXT, + buttonLabel: 'View Account', + onButtonClick: () => this.goToAccountDetailsModal(), + hide: buyingWithShapeshift, + }), + + this.renderRow({ + logo: h('i.fa.fa-tint.fa-2x'), + title: FAUCET_ROW_TITLE, + text: facuetRowText(networkName), + buttonLabel: 'Get Ether', + onButtonClick: () => toFaucet(network), + hide: !isTestNetwork || buyingWithShapeshift, + }), + + this.renderRow({ + logo: h('img.deposit-ether-modal__buy-row__coinbase-logo', { + src: '../../../images/coinbase logo.png', + }), + title: COINBASE_ROW_TITLE, + text: COINBASE_ROW_TEXT, + buttonLabel: 'Continue to Coinbase', + onButtonClick: () => toCoinbase(address), + hide: isTestNetwork || buyingWithShapeshift, + }), + + this.renderRow({ + logo: h('img.deposit-ether-modal__buy-row__shapeshift-logo', { + src: '../../../images/shapeshift logo.png', + }), + title: SHAPESHIFT_ROW_TITLE, + text: SHAPESHIFT_ROW_TEXT, + buttonLabel: 'Buy with Shapeshift', + onButtonClick: () => this.setState({ buyingWithShapeshift: true }), + hide: isTestNetwork, + hideButton: buyingWithShapeshift, + hideTitle: buyingWithShapeshift, + onBackClick: () => this.setState({ buyingWithShapeshift: false }), + className: buyingWithShapeshift && 'deposit-ether-modal__buy-row__shapeshift-buy', + }), + + buyingWithShapeshift && h(ShapeshiftForm), + + ]), + ]) +} + +DepositEtherModal.prototype.goToAccountDetailsModal = function () { + this.props.hideModal() + this.props.showAccountDetailModal() +} diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 2ff6accaa..afb2a2175 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -9,6 +9,7 @@ const isPopupOrNotification = require('../../../../app/scripts/lib/is-popup-or-n // Modal Components const BuyOptions = require('./buy-options-modal') +const DepositEtherModal = require('./deposit-ether-modal') const AccountDetailsModal = require('./account-details-modal') const EditAccountNameModal = require('./edit-account-name-modal') const ExportPrivateKeyModal = require('./export-private-key-modal') @@ -73,6 +74,37 @@ const MODALS = { }, }, + DEPOSIT_ETHER: { + contents: [ + h(DepositEtherModal, {}, []), + ], + mobileModalStyle: { + width: '100%', + height: '100%', + transform: 'none', + left: '0', + right: '0', + margin: '0 auto', + boxShadow: '0 0 7px 0 rgba(0,0,0,0.08)', + top: '0', + display: 'flex', + }, + laptopModalStyle: { + width: '900px', + maxWidth: '900px', + top: 'calc(10% + 10px)', + left: '0', + right: '0', + margin: '0 auto', + boxShadow: '0 0 6px 0 rgba(0,0,0,0.3)', + borderRadius: '8px', + transform: 'none', + }, + contentStyle: { + borderRadius: '8px', + }, + }, + EDIT_ACCOUNT_NAME: { contents: [ h(EditAccountNameModal, {}, []), diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js index c5993e3d3..2270b8236 100644 --- a/ui/app/components/shapeshift-form.js +++ b/ui/app/components/shapeshift-form.js @@ -1,308 +1,242 @@ -const PersistentForm = require('../../lib/persistent-form') const h = require('react-hyperscript') const inherits = require('util').inherits +const Component = require('react').Component const connect = require('react-redux').connect -const actions = require('../actions') -const Qr = require('./qr-code') -const isValidAddress = require('../util').isValidAddress -module.exports = connect(mapStateToProps)(ShapeshiftForm) +const classnames = require('classnames') +const { qrcode } = require('qrcode-npm') +const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../actions') +const { isValidAddress } = require('../util') +const SimpleDropdown = require('./dropdowns/simple-dropdown') function mapStateToProps (state) { + const { + coinOptions, + tokenExchangeRates, + selectedAddress, + } = state.metamask + return { - warning: state.appState.warning, - isSubLoading: state.appState.isSubLoading, - qrRequested: state.appState.qrRequested, + coinOptions, + tokenExchangeRates, + selectedAddress, } } -inherits(ShapeshiftForm, PersistentForm) +function mapDispatchToProps (dispatch) { + return { + shapeShiftSubview: () => dispatch(shapeShiftSubview()), + pairUpdate: coin => dispatch(pairUpdate(coin)), + buyWithShapeShift: data => dispatch(buyWithShapeShift(data)), + } +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm) +inherits(ShapeshiftForm, Component) function ShapeshiftForm () { - PersistentForm.call(this) - this.persistentFormParentId = 'shapeshift-buy-form' + Component.call(this) + + this.state = { + depositCoin: 'btc', + refundAddress: '', + showQrCode: false, + depositAddress: '', + errorMessage: '', + isLoading: false, + bought: false, + } } -ShapeshiftForm.prototype.render = function () { - return this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain() +ShapeshiftForm.prototype.componentWillMount = function () { + this.props.shapeShiftSubview() } -ShapeshiftForm.prototype.renderMain = function () { - const marketinfo = this.props.buyView.formView.marketinfo - const coinOptions = this.props.buyView.formView.coinOptions - var coin = marketinfo.pair.split('_')[0].toUpperCase() - - return h('.flex-column', { - style: { - position: 'relative', - padding: '25px', - paddingTop: '5px', - width: '90%', - minHeight: '215px', - alignItems: 'center', - overflowY: 'auto', - }, - }, [ - h('.flex-row', { - style: { - justifyContent: 'center', - alignItems: 'baseline', - height: '42px', - }, - }, [ - h('img', { - src: coinOptions[coin].image, - width: '25px', - height: '25px', - style: { - marginRight: '5px', - }, - }), - - h('.input-container', { - position: 'relative', - }, [ - h('input#fromCoin.buy-inputs.ex-coins', { - type: 'text', - list: 'coinList', - autoFocus: true, - dataset: { - persistentFormId: 'input-coin', - }, - style: { - boxSizing: 'border-box', - }, - onChange: this.handleLiveInput.bind(this), - defaultValue: 'BTC', - }), +ShapeshiftForm.prototype.onCoinChange = function (e) { + const coin = e.target.value + this.setState({ + depositCoin: coin, + errorMessage: '', + }) + this.props.pairUpdate(coin) +} - this.renderCoinList(), +ShapeshiftForm.prototype.onBuyWithShapeShift = function () { + this.setState({ + isLoading: true, + showQrCode: true, + }) - h('i.fa.fa-pencil-square-o.edit-text', { - style: { - fontSize: '12px', - color: '#F7861C', - position: 'absolute', - }, - }), - ]), + const { + buyWithShapeShift, + selectedAddress: withdrawal, + } = this.props + const { + refundAddress: returnAddress, + depositCoin, + } = this.state + const pair = `${depositCoin}_eth` + const data = { + withdrawal, + pair, + returnAddress, + // Public api key + 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6', + } - h('.icon-control', { - style: { - position: 'relative', - }, - }, [ - // Not visible on the screen, can't see it on master. - - // h('i.fa.fa-refresh.fa-4.orange', { - // style: { - // bottom: '5px', - // left: '5px', - // color: '#F7861C', - // }, - // onClick: this.updateCoin.bind(this), - // }), - h('i.fa.fa-chevron-right.fa-4.orange', { - style: { - position: 'absolute', - bottom: '35%', - left: '0%', - color: '#F7861C', - }, - onClick: this.updateCoin.bind(this), - }), - ]), + if (isValidAddress(withdrawal)) { + buyWithShapeShift(data) + .then(d => this.setState({ + showQrCode: true, + depositAddress: d.deposit, + isLoading: false, + })) + .catch(() => this.setState({ + showQrCode: false, + errorMessage: 'Invalid Request', + isLoading: false, + })) + } +} - h('#toCoin.ex-coins', marketinfo.pair.split('_')[1].toUpperCase()), +ShapeshiftForm.prototype.renderMetadata = function (label, value) { + return h('div', {className: 'shapeshift-form__metadata-wrapper'}, [ - h('img', { - src: coinOptions[marketinfo.pair.split('_')[1].toUpperCase()].image, - width: '25px', - height: '25px', - style: { - marginLeft: '5px', - }, - }), + h('div.shapeshift-form__metadata-label', {}, [ + h('span', `${label}:`), ]), - h('.flex-column', { - style: { - marginTop: '1%', - alignItems: 'flex-start', - }, - }, [ - this.props.warning ? - this.props.warning && - h('span.error.flex-center', { - style: { - textAlign: 'center', - width: '229px', - height: '82px', - }, - }, this.props.warning) - : this.renderInfo(), - - this.renderRefundAddressForCoin(coin), + h('div.shapeshift-form__metadata-value', {}, [ + h('span', value), ]), ]) } -ShapeshiftForm.prototype.renderRefundAddressForCoin = function (coin) { - return h(this.activeToggle('.input-container'), { - style: { - marginTop: '1%', - }, - }, [ - - h('div', `${coin} Address:`), - - h('input#fromCoinAddress.buy-inputs', { - type: 'text', - placeholder: `Your ${coin} Refund Address`, - dataset: { - persistentFormId: 'refund-address', - - }, - style: { - boxSizing: 'border-box', - width: '227px', - height: '30px', - padding: ' 5px ', - }, - }), - - h('i.fa.fa-pencil-square-o.edit-text', { - style: { - fontSize: '12px', - color: '#F7861C', - position: 'absolute', - }, - }), - h('div.flex-row', { - style: { - justifyContent: 'flex-start', - }, - }, [ - h('button', { - onClick: this.shift.bind(this), - style: { - marginTop: '1%', - }, - }, - 'Submit'), - ]), +ShapeshiftForm.prototype.renderMarketInfo = function () { + const { depositCoin } = this.state + const coinPair = `${depositCoin}_eth` + const { tokenExchangeRates } = this.props + const { + limit, + rate, + minimum, + } = tokenExchangeRates[coinPair] || {} + + return h('div.shapeshift-form__metadata', {}, [ + + this.renderMetadata('Status', limit ? 'Available' : 'Unavailable'), + this.renderMetadata('Limit', limit), + this.renderMetadata('Exchange Rate', rate), + this.renderMetadata('Minimum', minimum), + ]) } -ShapeshiftForm.prototype.shift = function () { - var props = this.props - var withdrawal = this.props.buyView.buyAddress - var returnAddress = document.getElementById('fromCoinAddress').value - var pair = this.props.buyView.formView.marketinfo.pair - var data = { - 'withdrawal': withdrawal, - 'pair': pair, - 'returnAddress': returnAddress, - // Public api key - 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6', - } - var message = [ - `Deposit Limit: ${props.buyView.formView.marketinfo.limit}`, - `Deposit Minimum:${props.buyView.formView.marketinfo.minimum}`, - ] - if (isValidAddress(withdrawal)) { - this.props.dispatch(actions.coinShiftRquest(data, message)) - } -} +ShapeshiftForm.prototype.renderQrCode = function () { + const { depositAddress, isLoading } = this.state + const qrImage = qrcode(4, 'M') + qrImage.addData(depositAddress) + qrImage.make() -ShapeshiftForm.prototype.renderCoinList = function () { - var list = Object.keys(this.props.buyView.formView.coinOptions).map((item) => { - return h('option', { - value: item, - }, item) - }) + return h('div.shapeshift-form', {}, [ - return h('datalist#coinList', { - onClick: (event) => { - event.preventDefault() - }, - }, list) -} + h('div.shapeshift-form__deposit-instruction', [ + 'Deposit your BTC to the address below:', + ]), -ShapeshiftForm.prototype.updateCoin = function (event) { - event.preventDefault() - const props = this.props - var coinOptions = this.props.buyView.formView.coinOptions - var coin = document.getElementById('fromCoin').value - - if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') { - var message = 'Not a valid coin' - return props.dispatch(actions.displayWarning(message)) - } else { - return props.dispatch(actions.pairUpdate(coin)) - } -} + h('div', depositAddress), -ShapeshiftForm.prototype.handleLiveInput = function () { - const props = this.props - var coinOptions = this.props.buyView.formView.coinOptions - var coin = document.getElementById('fromCoin').value + h('div.shapeshift-form__qr-code', [ + isLoading + ? h('img', { + src: 'images/loading.svg', + style: { width: '60px'}, + }) + : h('div', { + dangerouslySetInnerHTML: { __html: qrImage.createTableTag(4) }, + }), + ]), - if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') { - return null - } else { - return props.dispatch(actions.pairUpdate(coin)) - } -} + this.renderMarketInfo(), -ShapeshiftForm.prototype.renderInfo = function () { - const marketinfo = this.props.buyView.formView.marketinfo - const coinOptions = this.props.buyView.formView.coinOptions - var coin = marketinfo.pair.split('_')[0].toUpperCase() - - return h('span', { - style: { - }, - }, [ - h('h3.flex-row.text-transform-uppercase', { - style: { - color: '#868686', - paddingTop: '4px', - justifyContent: 'space-around', - textAlign: 'center', - fontSize: '17px', - }, - }, `Market Info for ${marketinfo.pair.replace('_', ' to ').toUpperCase()}:`), - h('.marketinfo', ['Status : ', `${coinOptions[coin].status}`]), - h('.marketinfo', ['Exchange Rate: ', `${marketinfo.rate}`]), - h('.marketinfo', ['Limit: ', `${marketinfo.limit}`]), - h('.marketinfo', ['Minimum : ', `${marketinfo.minimum}`]), ]) } -ShapeshiftForm.prototype.activeToggle = function (elementType) { - if (!this.props.buyView.formView.response || this.props.warning) return elementType - return `${elementType}.inactive` -} -ShapeshiftForm.prototype.renderLoading = function () { - return h('span', { - style: { - position: 'absolute', - left: '70px', - bottom: '194px', - background: 'transparent', - width: '229px', - height: '82px', - display: 'flex', - justifyContent: 'center', - }, - }, [ - h('img', { - style: { - width: '60px', - }, - src: 'images/loading.svg', - }), - ]) +ShapeshiftForm.prototype.render = function () { + const { coinOptions, btnClass } = this.props + const { depositCoin, errorMessage, showQrCode, depositAddress } = this.state + const coinPair = `${depositCoin}_eth` + const { tokenExchangeRates } = this.props + const token = tokenExchangeRates[coinPair] + + return h('div.shapeshift-form-wrapper', [ + showQrCode + ? this.renderQrCode() + : h('div.shapeshift-form', [ + h('div.shapeshift-form__selectors', [ + + h('div.shapeshift-form__selector', [ + + h('div.shapeshift-form__selector-label', 'Deposit'), + + h(SimpleDropdown, { + selectedOption: this.state.depositCoin, + onSelect: this.onCoinChange, + options: Object.entries(coinOptions).map(([coin]) => ({ + value: coin.toLowerCase(), + displayValue: coin, + })), + }), + + ]), + + h('div.icon.shapeshift-form__caret', { + style: { backgroundImage: 'url(images/caret-right.svg)'}, + }), + + h('div.shapeshift-form__selector', [ + + h('div.shapeshift-form__selector-label', [ + 'Receive', + ]), + + h('div.shapeshift-form__selector-input', ['ETH']), + + ]), + + ]), + + h('div', { + className: classnames('shapeshift-form__address-input-wrapper', { + 'shapeshift-form__address-input-wrapper--error': errorMessage, + }), + }, [ + + h('div.shapeshift-form__address-input-label', [ + 'Your Refund Address', + ]), + + h('input.shapeshift-form__address-input', { + type: 'text', + onChange: e => this.setState({ + refundAddress: e.target.value, + errorMessage: '', + }), + }), + + h('divshapeshift-form__address-input-error-message', [errorMessage]), + ]), + + this.renderMarketInfo(), + + ]), + + !depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', { + className: btnClass, + disabled: !token, + onClick: () => this.onBuyWithShapeShift(), + }, ['Buy']), + + ]) } diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js index 43973de63..111a77df4 100644 --- a/ui/app/components/shift-list-item.js +++ b/ui/app/components/shift-list-item.js @@ -16,6 +16,7 @@ module.exports = connect(mapStateToProps)(ShiftListItem) function mapStateToProps (state) { return { + selectedAddress: state.metamask.selectedAddress, conversionRate: state.metamask.conversionRate, currentCurrency: state.metamask.currentCurrency, } @@ -28,36 +29,39 @@ function ShiftListItem () { } ShiftListItem.prototype.render = function () { + const { selectedAddress, receivingAddress } = this.props return ( - h('div.tx-list-item.tx-list-clickable', { - style: { - paddingTop: '20px', - paddingBottom: '20px', - justifyContent: 'space-around', - alignItems: 'center', - }, - }, [ - h('div', { + selectedAddress === receivingAddress + ? h('div.tx-list-item.tx-list-clickable', { style: { - width: '0px', - position: 'relative', - bottom: '19px', + paddingTop: '20px', + paddingBottom: '20px', + justifyContent: 'space-around', + alignItems: 'center', }, }, [ - h('img', { - src: 'https://info.shapeshift.io/sites/default/files/logo.png', + h('div', { style: { - height: '35px', - width: '132px', - position: 'absolute', - clip: 'rect(0px,23px,34px,0px)', + width: '0px', + position: 'relative', + bottom: '19px', }, - }), - ]), + }, [ + h('img', { + src: 'https://info.shapeshift.io/sites/default/files/logo.png', + style: { + height: '35px', + width: '132px', + position: 'absolute', + clip: 'rect(0px,23px,34px,0px)', + }, + }), + ]), - this.renderInfo(), - this.renderUtilComponents(), - ]) + this.renderInfo(), + this.renderUtilComponents(), + ]) + : null ) } diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js index 70722f43e..50e328dac 100644 --- a/ui/app/components/tx-list.js +++ b/ui/app/components/tx-list.js @@ -52,7 +52,7 @@ TxList.prototype.render = function () { TxList.prototype.renderTransaction = function () { const { txsToRender, conversionRate } = this.props return txsToRender.length - ? txsToRender.map((transaction, i) => this.renderTransactionListItem(transaction, conversionRate)) + ? txsToRender.map((transaction, i) => this.renderTransactionListItem(transaction, conversionRate, i)) : [h( 'div.tx-list-item.tx-list-item--empty', { key: 'tx-list-none' }, @@ -61,12 +61,16 @@ TxList.prototype.renderTransaction = function () { } // TODO: Consider moving TxListItem into a separate component -TxList.prototype.renderTransactionListItem = function (transaction, conversionRate) { +TxList.prototype.renderTransactionListItem = function (transaction, conversionRate, index) { // console.log({transaction}) // refer to transaction-list.js:line 58 if (transaction.key === 'shapeshift') { - return h(ShiftListItem, transaction) + return h('div', { + key: `shapeshift${index}`, + }, [ + h(ShiftListItem, transaction), + ]) } const props = { diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js index e42a20c85..949d91f6f 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -73,7 +73,7 @@ TxView.prototype.renderButtons = function () { textAlign: 'center', }, onClick: () => showModal({ - name: 'BUY', + name: 'DEPOSIT_ETHER', }), }, 'DEPOSIT'), diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss index 9b64564d6..2431e2f63 100644 --- a/ui/app/css/itcss/components/modal.scss +++ b/ui/app/css/itcss/components/modal.scss @@ -598,4 +598,256 @@ justify-content: center; font-size: 17px; color: $nile-blue; -} \ No newline at end of file +} + +// Deposit Ether Modal +.deposit-ether-modal { + border-radius: 8px; + font-family: Roboto; + display: flex; + flex-flow: column; + height: 100%; + + &__header { + width: 100%; + border-radius: 8px 8px 0 0; + background-color: $mid-gray; + display: flex; + position: relative; + padding: 25px; + flex-flow: column; + align-items: flex-start; + + &__title { + color: $white; + font-size: 24px; + line-height: 32px; + } + + &__description { + color: $white; + font-size: 16px; + line-height: 22px; + margin-top: 10px; + } + + &__close::after { + content: '\00D7'; + font-size: 2em; + color: $white; + position: absolute; + top: 20.8px; + right: 28px; + cursor: pointer; + } + } + + &__buy-rows { + width: 100%; + padding: 33px; + padding-top: 0px; + display: flex; + flex-flow: column nowrap; + flex: 1; + overflow-y: auto; + + @media screen and (max-width: 575px) { + height: 0; + } + } + + &__buy-row { + border-bottom: 1px solid $alto; + display: flex; + justify-content: space-between; + align-items: center; + flex: 1; + padding-bottom: 25px; + padding-top: 25px; + + @media screen and (max-width: 575px) { + min-height: 360px; + flex-flow: column; + justify-content: center; + padding-top: 45px; + } + + &__back { + position: absolute; + top: 10px; + left: 0px; + } + + &__shapeshift-buy { + padding-top: 25px; + position: relative; + @media screen and (max-width: 575px) { + display: flex; + justify-content: space-between; + align-items: center; + flex: 1; + padding-bottom: 25px; + flex-flow: column; + justify-content: center; + padding-top: 20px; + min-height: 240px; + border: none; + } + } + + &__logo { + display: flex; + justify-content: center; + flex: 0.3 1 auto; + + @media screen and (min-width: 575px) { + min-width: 215px; + } + } + + &__coinbase-logo { + height: 40px; + width: 180px; + } + + &__shapeshift-logo { + height: 60px; + width: 174px; + } + + &__eth-logo { + border-radius: 50%; + width: 68px; + height: 68px; + border: 3px solid $tundora; + z-index: 25; + padding: 4px; + background-color: #fff; + } + + &__right { + display: flex; + } + + &__description { + color: $cape-cod; + flex: 0.5 1 auto; + + @media screen and (min-width: 575px) { + min-width: 315px; + } + + &__title { + font-size: 20px; + line-height: 30px; + } + + &__text { + font-size: 14px; + line-height: 22px; + margin-top: 7px; + } + } + + &__button { + display: flex; + justify-content: flex-end; + + @media screen and (min-width: 575px) { + min-width: 300px; + } + } + } + + &__buy-row:last-of-type { + border-bottom: 0px; + } + + &__deposit-button, .shapeshift-form__shapeshift-buy-btn { + height: 54px; + 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 { + display: flex; + flex-flow: column; + justify-content: center; + align-items: center; + margin-top: 28px; + flex: 1 0 auto; + + .shapeshift-form { + width: auto; + + &__caret { + width: auto; + flex: 1; + } + } + } + + .shapeshift-form__shapeshift-buy-btn { + margin-top: 10px; + } + + .simple-dropdown { + color: #5B5D67; + font-size: 16px; + font-weight: 300; + line-height: 21px; + border: 1px solid #D8D8D8; + background-color: #FFFFFF; + text-align: center; + width: 100%; + height: 45px; + line-height: 44px; + font-family: Montserrat Light; + } + + .simple-dropdown__selected { + text-align: center; + } +} + +//Notification Modal + +.notification-modal-wrapper { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + position: relative; + border: 1px solid $alto; + box-shadow: 0 0 2px 2px $alto; + font-family: Roboto; +} + +.notification-modal-header { + background: $wild-sand; + width: 100%; + display: flex; + justify-content: center; + padding: 30px; + font-size: 22px; + color: $nile-blue; + height: 79px; +} + +.notification-modal-message { + padding: 20px; +} + +.notification-modal-message { + width: 100%; + display: flex; + justify-content: center; + font-size: 17px; + color: $nile-blue; +} diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index 387d14b5f..edc376c17 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -42,6 +42,8 @@ $malibu-blue: #7ac9fd; $athens-grey: #e9edf0; $jaffa: #f28930; $geyser: #d2d8dd; +$mid-gray: #5b5d67; +$cape-cod: #38393a; /* Z-Indicies diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 3a4fb536d..e96dea0be 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -58,6 +58,7 @@ function reduceApp (state, action) { isLoading: false, // Used to display error text warning: null, + buyView: {}, }, state.appState) switch (action.type) { @@ -591,8 +592,8 @@ function reduceApp (state, action) { marketinfo: action.value.marketinfo, coinOptions: action.value.coinOptions, }, - buyAddress: appState.buyView.buyAddress, - amount: appState.buyView.amount, + buyAddress: action.value.buyAddress || appState.buyView.buyAddress, + amount: appState.buyView.amount || 0, }, }) -- cgit From bdcee058dc278c46c828f376476f121417481385 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 9 Jan 2018 16:45:39 -0800 Subject: Fix styling in initialization --- ui/app/app.js | 6 +++++- ui/app/css/itcss/components/header.scss | 13 +++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/app/app.js b/ui/app/app.js index c6fce0e47..3fca8ccc1 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -3,6 +3,8 @@ const Component = require('react').Component const connect = require('react-redux').connect const h = require('react-hyperscript') const actions = require('./actions') +const classnames = require('classnames') + // mascara const MascaraFirstTime = require('../../mascara/src/app/first-time').default const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default @@ -243,7 +245,9 @@ App.prototype.renderAppBar = function () { }, [ h('.app-header.flex-row.flex-space-between', { - style: {}, + className: classnames({ + 'app-header--initialized': !isOnboarding, + }), }, [ h('div.app-header-contents', {}, [ h('div.left-menu-wrapper', { diff --git a/ui/app/css/itcss/components/header.scss b/ui/app/css/itcss/components/header.scss index a6332f819..e27444084 100644 --- a/ui/app/css/itcss/components/header.scss +++ b/ui/app/css/itcss/components/header.scss @@ -17,7 +17,16 @@ @media screen and (min-width: 576px) { height: 75px; justify-content: center; + } + + .metafox-icon { + cursor: pointer; + } +} +.app-header--initialized { + + @media screen and (min-width: 576px) { &::after { content: ''; position: absolute; @@ -27,10 +36,6 @@ bottom: -32px; } } - - .metafox-icon { - cursor: pointer; - } } .app-header-contents { -- cgit From 980e1bfcf82361185f6d1b22abd9593ba166825e Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 10 Jan 2018 14:55:38 -0330 Subject: New add account page with create and import options. --- ui/app/accounts/import/index.js | 34 +--- ui/app/accounts/import/json.js | 40 ++--- ui/app/accounts/import/private-key.js | 61 +++---- ui/app/accounts/new-account/create-form.js | 96 +++++++++++ ui/app/accounts/new-account/index.js | 82 ++++++++++ ui/app/actions.js | 18 ++ ui/app/app.js | 5 + ui/app/components/account-menu/index.js | 16 +- .../dropdowns/components/account-dropdowns.js | 10 +- ui/app/css/itcss/components/index.scss | 2 + ui/app/css/itcss/components/new-account.scss | 181 +++++++++++++++++++++ ui/app/reducers/app.js | 19 ++- ui/app/selectors.js | 6 + 13 files changed, 475 insertions(+), 95 deletions(-) create mode 100644 ui/app/accounts/new-account/create-form.js create mode 100644 ui/app/accounts/new-account/index.js create mode 100644 ui/app/css/itcss/components/new-account.scss (limited to 'ui') diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js index b7d9a9537..0c901c09b 100644 --- a/ui/app/accounts/import/index.js +++ b/ui/app/accounts/import/index.js @@ -2,7 +2,6 @@ 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') import Select from 'react-select' // Subviews @@ -34,37 +33,14 @@ AccountImportSubview.prototype.render = function () { const { type } = state return ( - h('div.flex-center', { - style: { - flexDirection: 'column', - marginTop: '32px', - }, - }, [ - h('.section-title.flex-row.flex-center', [ - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: (event) => { - props.dispatch(actions.goHome()) - }, - }), - h('h2.page-subtitle', 'Import Accounts'), - ]), - h('div', { - style: { - padding: '10px 0', - width: '260px', - color: 'rgb(174, 174, 174)', - }, - }, [ + h('div.new-account-import-form', [ - h('h3', { style: { padding: '3px' } }, 'SELECT TYPE'), + h('div.new-account-import-form__select-section', [ - h('style', ` - .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label { - color: rgb(174,174,174); - } - `), + h('div.new-account-import-form__select-label', 'SELECT TYPE'), h(Select, { + className: 'new-account-import-form__select', name: 'import-type-select', clearable: false, value: type || menuItems[0], @@ -75,10 +51,10 @@ AccountImportSubview.prototype.render = function () { } }), onChange: (opt) => { - props.dispatch(actions.showImportPage()) this.setState({ type: opt.value }) }, }), + ]), this.renderImportView(), diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js index 486ed8886..9cefcfa77 100644 --- a/ui/app/accounts/import/json.js +++ b/ui/app/accounts/import/json.js @@ -24,14 +24,7 @@ JsonImportSubview.prototype.render = function () { const { error } = this.props return ( - h('div', { - style: { - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - padding: '5px 15px 0px 15px', - }, - }, [ + h('div.new-account-import-form__json', [ h('p', 'Used by a variety of different clients'), h('a.warning', { href: HELP_LINK, target: '_blank' }, 'File import not working? Click here!'), @@ -40,28 +33,35 @@ JsonImportSubview.prototype.render = function () { readAs: 'text', onLoad: this.onLoad.bind(this), style: { - margin: '20px 0px 12px 20px', + margin: '20px 0px 12px 34%', fontSize: '15px', + display: 'flex', + justifyContent: 'center', }, }), - h('input.large-input.letter-spacey', { + h('input.new-account-import-form__input-password', { type: 'password', placeholder: 'Enter password', id: 'json-password-box', onKeyPress: this.createKeyringOnEnter.bind(this), - style: { - width: 260, - marginTop: 12, - }, }), - h('button.primary', { - onClick: this.createNewKeychain.bind(this), - style: { - margin: 12, - }, - }, 'Import'), + h('div.new-account-create-form__buttons', {}, [ + + h('button.new-account-create-form__button-cancel', { + onClick: () => this.props.goHome(), + }, [ + 'CANCEL', + ]), + + h('button.new-account-create-form__button-create', { + onClick: () => this.createNewKeychain.bind(this), + }, [ + 'IMPORT', + ]), + + ]), error ? h('span.error', error) : null, ]) diff --git a/ui/app/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js index e214bcbbe..43afbca87 100644 --- a/ui/app/accounts/import/private-key.js +++ b/ui/app/accounts/import/private-key.js @@ -4,7 +4,7 @@ const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('../../actions') -module.exports = connect(mapStateToProps)(PrivateKeyImportView) +module.exports = connect(mapStateToProps, mapDispatchToProps)(PrivateKeyImportView) function mapStateToProps (state) { return { @@ -12,45 +12,49 @@ function mapStateToProps (state) { } } +function mapDispatchToProps (dispatch) { + return { + goHome: () => dispatch(actions.goHome()), + importNewAccount: (strategy, [ privateKey ]) => { + dispatch(actions.importNewAccount(strategy, [ privateKey ])) + }, + displayWarning: () => dispatch(actions.displayWarning(null)), + } +} + inherits(PrivateKeyImportView, Component) function PrivateKeyImportView () { Component.call(this) } -PrivateKeyImportView.prototype.componentWillUnmount = function () { - this.props.dispatch(actions.displayWarning(null)) -} - PrivateKeyImportView.prototype.render = function () { - const { error } = this.props + const { error, goHome } = 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('div.new-account-import-form__private-key', [ + h('span.new-account-create-form__instruction', 'Paste your private key string here:'), - h('input.large-input.letter-spacey', { + h('input.new-account-import-form__input-password', { type: 'password', id: 'private-key-box', - onKeyPress: this.createKeyringOnEnter.bind(this), - style: { - width: 260, - marginTop: 12, - }, + onKeyPress: () => this.createKeyringOnEnter(), }), - h('button.primary', { - onClick: this.createNewKeychain.bind(this), - style: { - margin: 12, - }, - }, 'Import'), + h('div.new-account-create-form__buttons', {}, [ + + h('button.new-account-create-form__button-cancel', { + onClick: () => goHome(), + }, [ + 'CANCEL', + ]), + + h('button.new-account-create-form__button-create', { + onClick: () => this.createNewKeychain(), + }, [ + 'IMPORT', + ]), + + ]), error ? h('span.error', error) : null, ]) @@ -67,5 +71,6 @@ PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) { PrivateKeyImportView.prototype.createNewKeychain = function () { const input = document.getElementById('private-key-box') const privateKey = input.value - this.props.dispatch(actions.importNewAccount('Private Key', [ privateKey ])) + + this.props.importNewAccount('Private Key', [ privateKey ]) } diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/accounts/new-account/create-form.js new file mode 100644 index 000000000..494726ae4 --- /dev/null +++ b/ui/app/accounts/new-account/create-form.js @@ -0,0 +1,96 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') +const { connect } = require('react-redux') +const actions = require('../../actions') + +class NewAccountCreateForm extends Component { + constructor (props) { + super(props) + const { numberOfExistingAccounts = 0 } = props + const newAccountNumber = numberOfExistingAccounts + 1 + + this.state = { + newAccountName: `Account ${newAccountNumber}`, + } + } + + render () { + const { newAccountName } = this.state + + return h('div.new-account-create-form', [ + + h('div.new-account-create-form__input-label', {}, [ + 'Account Name', + ]), + + h('div.new-account-create-form__input-wrapper', {}, [ + h('input.new-account-create-form__input', { + value: this.state.newAccountName, + placeholder: 'E.g. My new account', + onChange: event => this.setState({ newAccountName: event.target.value }), + }, []), + ]), + + h('div.new-account-create-form__buttons', {}, [ + + h('button.new-account-create-form__button-cancel', { + onClick: () => this.props.goHome(), + }, [ + 'CANCEL', + ]), + + h('button.new-account-create-form__button-create', { + onClick: () => this.props.createAccount(newAccountName), + }, [ + 'CREATE', + ]), + + ]), + + ]) + } +} + +NewAccountCreateForm.propTypes = { + hideModal: PropTypes.func, + showImportPage: PropTypes.func, + createAccount: PropTypes.func, + goHome: PropTypes.func, + numberOfExistingAccounts: PropTypes.number, +} + +const mapStateToProps = state => { + const { metamask: { network, selectedAddress, identities = {} } } = state + const numberOfExistingAccounts = Object.keys(identities).length + + return { + network, + address: selectedAddress, + numberOfExistingAccounts, + } +} + +const mapDispatchToProps = dispatch => { + return { + toCoinbase: (address) => { + dispatch(actions.buyEth({ network: '1', address, amount: 0 })) + }, + hideModal: () => { + dispatch(actions.hideModal()) + }, + createAccount: (newAccountName) => { + dispatch(actions.addNewAccount()) + .then((newAccountAddress) => { + if (newAccountName) { + dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName)) + } + dispatch(actions.goHome()) + }) + }, + showImportPage: () => dispatch(actions.showImportPage()), + goHome: () => dispatch(actions.goHome()), + } +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountCreateForm) diff --git a/ui/app/accounts/new-account/index.js b/ui/app/accounts/new-account/index.js new file mode 100644 index 000000000..cd096a403 --- /dev/null +++ b/ui/app/accounts/new-account/index.js @@ -0,0 +1,82 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const connect = require('react-redux').connect +const actions = require('../../actions') +const { getCurrentViewContext } = require('../../selectors') +const classnames = require('classnames') + +const NewAccountCreateForm = require('./create-form') +const NewAccountImportForm = require('../import') + +function mapStateToProps (state) { + return { + displayedForm: getCurrentViewContext(state), + } +} + +function mapDispatchToProps (dispatch) { + return { + // Is this supposed to be used somewhere? + displayForm: form => dispatch(actions.setNewAccountForm(form)), + showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), + showExportPrivateKeyModal: () => { + dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' })) + }, + hideModal: () => dispatch(actions.hideModal()), + saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)), + } +} + +inherits(AccountDetailsModal, Component) +function AccountDetailsModal (props) { + Component.call(this) + + this.state = { + displayedForm: props.displayedForm, + } +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) + +AccountDetailsModal.prototype.render = function () { + const { displayedForm, displayForm } = this.props + + return h('div.new-account', {}, [ + + h('div.new-account__header', [ + + h('div.new-account__title', 'New Account'), + + h('div.new-account__tabs', [ + + h('div.new-account__tabs__tab', { + className: classnames('new-account__tabs__tab', { + 'new-account__tabs__selected': displayedForm === 'CREATE', + 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'CREATE', + }), + onClick: () => displayForm('CREATE'), + }, 'Create'), + + h('div.new-account__tabs__tab', { + className: classnames('new-account__tabs__tab', { + 'new-account__tabs__selected': displayedForm === 'IMPORT', + 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'IMPORT', + }), + onClick: () => displayForm('IMPORT'), + }, 'Import'), + + ]), + + ]), + + h('div.new-account__form', [ + + displayedForm === 'CREATE' + ? h(NewAccountCreateForm) + : h(NewAccountImportForm), + + ]), + + ]) +} diff --git a/ui/app/actions.js b/ui/app/actions.js index 0d96d2b59..192a73f76 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -50,12 +50,16 @@ var actions = { SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED', SHOW_INFO_PAGE: 'SHOW_INFO_PAGE', SHOW_IMPORT_PAGE: 'SHOW_IMPORT_PAGE', + SHOW_NEW_ACCOUNT_PAGE: 'SHOW_NEW_ACCOUNT_PAGE', + SET_NEW_ACCOUNT_FORM: 'SET_NEW_ACCOUNT_FORM', unlockMetamask: unlockMetamask, unlockFailed: unlockFailed, showCreateVault: showCreateVault, showRestoreVault: showRestoreVault, showInitializeMenu: showInitializeMenu, showImportPage, + showNewAccountPage, + setNewAccountForm, createNewVaultAndKeychain: createNewVaultAndKeychain, createNewVaultAndRestore: createNewVaultAndRestore, createNewVaultInProgress: createNewVaultInProgress, @@ -829,6 +833,20 @@ function showImportPage () { } } +function showNewAccountPage (formToSelect) { + return { + type: actions.SHOW_NEW_ACCOUNT_PAGE, + formToSelect, + } +} + +function setNewAccountForm (formToSelect) { + return { + type: actions.SET_NEW_ACCOUNT_FORM, + formToSelect, + } +} + function createNewVaultInProgress () { return { type: actions.CREATE_NEW_VAULT_IN_PROGRESS, diff --git a/ui/app/app.js b/ui/app/app.js index e24ab7109..866801dd5 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -26,6 +26,7 @@ const WalletView = require('./components/wallet-view') const Settings = require('./settings') const AddTokenScreen = require('./add-token') const Import = require('./accounts/import') +const NewAccount = require('./accounts/new-account') const Loading = require('./components/loading') const NetworkIndicator = require('./components/network') const Identicon = require('./components/identicon') @@ -435,6 +436,10 @@ App.prototype.renderPrimary = function () { log.debug('rendering import screen') return h(Import, {key: 'import-menu'}) + case 'new-account-page': + log.debug('rendering new account screen') + return h(NewAccount, {key: 'new-account'}) + case 'reveal-seed-conf': log.debug('rendering reveal seed confirmation screen') return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'}) diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index 1b62b42fb..aeb8a0b38 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -42,13 +42,8 @@ function mapDispatchToProps (dispatch) { dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, - showNewAccountModal: () => { - dispatch(actions.showModal({ name: 'NEW_ACCOUNT' })) - dispatch(actions.hideSidebar()) - dispatch(actions.toggleAccountMenu()) - }, - showImportPage: () => { - dispatch(actions.showImportPage()) + showNewAccountPage: (formToSelect) => { + dispatch(actions.showNewAccountPage(formToSelect)) dispatch(actions.hideSidebar()) dispatch(actions.toggleAccountMenu()) }, @@ -64,8 +59,7 @@ AccountMenu.prototype.render = function () { const { isAccountMenuOpen, toggleAccountMenu, - showNewAccountModal, - showImportPage, + showNewAccountPage, lockMetamask, showConfigPage, showInfoPage, @@ -85,12 +79,12 @@ AccountMenu.prototype.render = function () { h('div.account-menu__accounts', this.renderAccounts()), h(Divider), h(Item, { - onClick: showNewAccountModal, + onClick: () => showNewAccountPage('CREATE'), icon: h('img', { src: 'images/plus-btn-white.svg' }), text: 'Create Account', }), h(Item, { - onClick: showImportPage, + onClick: () => showNewAccountPage('IMPORT'), icon: h('img', { src: 'images/import-account.svg' }), text: 'Import Account', }), diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js index 58326b13c..f97ac0691 100644 --- a/ui/app/components/dropdowns/components/account-dropdowns.js +++ b/ui/app/components/dropdowns/components/account-dropdowns.js @@ -199,7 +199,7 @@ class AccountDropdowns extends Component { {}, menuItemStyles, ), - onClick: () => actions.showNewAccountModal(), + onClick: () => actions.showNewAccountPageCreateForm(), }, [ h( @@ -228,7 +228,7 @@ class AccountDropdowns extends Component { actions.hideSidebar() } }, - onClick: () => actions.showImportPage(), + onClick: () => actions.showNewAccountPageImportForm(), style: Object.assign( {}, menuItemStyles, @@ -457,9 +457,7 @@ const mapDispatchToProps = (dispatch) => { identity, })) }, - showNewAccountModal: () => { - dispatch(actions.showModal({ name: 'NEW_ACCOUNT' })) - }, + showNewAccountPageCreateForm: () => dispatch(actions.showNewAccountPage({ form: 'CREATE' })), showExportPrivateKeyModal: () => { dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' })) }, @@ -467,7 +465,7 @@ const mapDispatchToProps = (dispatch) => { dispatch(actions.showAddTokenPage()) }, addNewAccount: () => dispatch(actions.addNewAccount()), - showImportPage: () => dispatch(actions.showImportPage()), + showNewAccountPageImportForm: () => dispatch(actions.showNewAccountPage({ form: 'IMPORT' })), showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), }, } diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss index dfb4f23f0..d1b9b6277 100644 --- a/ui/app/css/itcss/components/index.scss +++ b/ui/app/css/itcss/components/index.scss @@ -51,3 +51,5 @@ @import './account-dropdown-mini.scss'; @import './editable-label.scss'; + +@import './new-account.scss'; diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss new file mode 100644 index 000000000..e14f567e1 --- /dev/null +++ b/ui/app/css/itcss/components/new-account.scss @@ -0,0 +1,181 @@ +.new-account { + width: 376px; + background-color: #FFFFFF; + box-shadow: 0 0 7px 0 rgba(0,0,0,0.08); + z-index: 25; + padding-bottom: 31px; + + &__header { + display: flex; + flex-flow: column; + border-bottom: 1px solid $geyser; + } + + &__title { + color: $tundora; + font-family: Roboto; + font-size: 32px; + font-weight: 500; + line-height: 43px; + margin-top: 22px; + margin-left: 29px; + } + + &__tabs { + margin-left: 22px; + display: flex; + margin-top: 10px; + + &__tab { + height: 54px; + width: 75px; + padding: 15px 10px; + color: $dusty-gray; + font-family: Roboto; + font-size: 18px; + line-height: 24px; + text-align: center; + } + + &__tab:first-of-type { + margin-right: 20px; + } + + &__unselected:hover { + color: $black; + border-bottom: none; + } + + &__selected { + color: $curious-blue; + border-bottom: 3px solid $curious-blue; + } + } + +} + +.new-account-import-form { + &__select-section { + display: flex; + justify-content: space-evenly; + align-items: center; + margin-top: 29px; + } + + &__select-label { + color: $scorpion; + font-family: Roboto; + font-size: 16px; + line-height: 21px; + } + + &__select { + height: 54px; + width: 210px; + border: 1px solid #D2D8DD; + border-radius: 4px; + background-color: #FFFFFF; + display: flex; + align-items: center; + + .Select-control, + .Select-control:hover { + border: none; + box-shadow: none; + } + } + + &__instruction { + color: $scorpion; + font-family: Roboto; + font-size: 16px; + line-height: 21px; + align-self: flex-start; + margin-left: 30px; + } + + &__private-key { + display: flex; + flex-flow: column; + align-items: center; + margin-top: 34px; + } + + &__input-password { + height: 54px; + width: 315px; + border: 1px solid $geyser; + border-radius: 4px; + background-color: $white; + margin-top: 16px; + } + + &__json { + display: flex; + flex-flow: column; + align-items: center; + margin-top: 29px; + } +} + +.new-account-create-form { + display: flex; + flex-flow: column; + align-items: center; + + &__input-label { + color: $scorpion; + font-family: Roboto; + font-size: 16px; + line-height: 21px; + margin-top: 29px; + align-self: flex-start; + margin-left: 30px; + } + + &__input { + height: 54px; + width: 315.84px; + border: 1px solid $geyser; + border-radius: 4px; + background-color: $white; + color: $scorpion; + font-family: Roboto; + font-size: 16px; + line-height: 21px; + margin-top: 15px; + } + + &__buttons { + margin-top: 39px; + display: flex; + width: 100%; + justify-content: space-evenly; + } + + &__button-cancel, + &__button-create { + height: 55px; + width: 150px; + border-radius: 2px; + 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; + } +} \ No newline at end of file diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index e96dea0be..b4950e9d9 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -170,7 +170,6 @@ function reduceApp (state, action) { }) case actions.SHOW_IMPORT_PAGE: - return extend(appState, { currentView: { name: 'import-menu', @@ -179,6 +178,24 @@ function reduceApp (state, action) { warning: null, }) + case actions.SHOW_NEW_ACCOUNT_PAGE: + return extend(appState, { + currentView: { + name: 'new-account-page', + context: action.formToSelect, + }, + transForward: true, + warning: null, + }) + + case actions.SET_NEW_ACCOUNT_FORM: + return extend(appState, { + currentView: { + name: appState.currentView.name, + context: action.formToSelect, + }, + }) + case actions.SHOW_INFO_PAGE: return extend(appState, { currentView: { diff --git a/ui/app/selectors.js b/ui/app/selectors.js index 22ef439c4..38a96c48b 100644 --- a/ui/app/selectors.js +++ b/ui/app/selectors.js @@ -26,6 +26,7 @@ const selectors = { getSelectedTokenContract, autoAddToBetaUI, getSendMaxModeState, + getCurrentViewContext, } module.exports = selectors @@ -180,4 +181,9 @@ function autoAddToBetaUI (state) { const userIsNotInBeta = !state.metamask.featureFlags.betaUI return userIsNotInBeta && userPassesThreshold +} + +function getCurrentViewContext (state) { + const { currentView = {} } = state.appState + return currentView.context } \ No newline at end of file -- cgit From 2bc85ea72f2b53f763149dafd3a7787de9016635 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 12 Jan 2018 13:59:43 -0330 Subject: Fix input box padding and select highlight in new account create and import page. --- ui/app/accounts/new-account/index.js | 1 - ui/app/css/itcss/components/new-account.scss | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/accounts/new-account/index.js b/ui/app/accounts/new-account/index.js index cd096a403..acf0dc6e4 100644 --- a/ui/app/accounts/new-account/index.js +++ b/ui/app/accounts/new-account/index.js @@ -17,7 +17,6 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - // Is this supposed to be used somewhere? displayForm: form => dispatch(actions.setNewAccountForm(form)), showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), showExportPrivateKeyModal: () => { diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss index e14f567e1..c5e4ea761 100644 --- a/ui/app/css/itcss/components/new-account.scss +++ b/ui/app/css/itcss/components/new-account.scss @@ -80,8 +80,14 @@ .Select-control, .Select-control:hover { + height: 100%; border: none; box-shadow: none; + + .Select-value { + display: flex; + align-items: center; + } } } @@ -108,6 +114,10 @@ border-radius: 4px; background-color: $white; margin-top: 16px; + color: $scorpion; + font-family: Roboto; + font-size: 16px; + padding: 0px 20px; } &__json { @@ -144,6 +154,7 @@ font-size: 16px; line-height: 21px; margin-top: 15px; + padding: 0px 20px; } &__buttons { -- cgit From dce6dcf437ecb7769d45ee38f1d2227a74f09ca6 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Fri, 12 Jan 2018 16:16:28 -0800 Subject: Fix Add Token button order, styling --- ui/app/add-token.js | 8 ++++---- ui/app/css/itcss/components/add-token.scss | 22 ++++++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'ui') diff --git a/ui/app/add-token.js b/ui/app/add-token.js index 10aaae103..9f1357591 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -345,12 +345,12 @@ AddTokenScreen.prototype.render = function () { ]), ]), h('div.add-token__buttons', [ - h('button.btn-secondary', { - onClick: this.onNext, - }, 'Next'), - h('button.btn-tertiary', { + h('button.btn-cancel.add-token__button', { onClick: goHome, }, 'Cancel'), + h('button.btn-clear.add-token__button', { + onClick: this.onNext, + }, 'Next'), ]), ]) ) diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss index 5f6d0fcff..13020f62f 100644 --- a/ui/app/css/itcss/components/add-token.scss +++ b/ui/app/css/itcss/components/add-token.scss @@ -94,6 +94,7 @@ padding: 12px 0; font-weight: 600; cursor: pointer; + position: relative; &:hover { background-color: rgba(0, 0, 0, .05); @@ -164,9 +165,18 @@ &__buttons { display: flex; - flex-flow: column nowrap; + flex-flow: row nowrap; margin: 30px 0 51px; flex: 0 0 auto; + align-items: center; + justify-content: center; + } + + &__button { + flex: 1 0 141px; + margin: 0 12px; + padding: 10px 22px; + height: 54px; } &__token-icons-container { @@ -324,18 +334,10 @@ } &__buttons { - flex-flow: row nowrap; - width: 100%; - align-items: center; - justify-content: center; padding: 12px 0; margin: 0; border-top: 1px solid $gallery; - - button { - flex: 1 0 auto; - margin: 0 12px; - } + width: 100%; } } } -- cgit From b42baacdf4683be560c5632752347eadf77f1d0f Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Fri, 12 Jan 2018 16:41:29 -0800 Subject: Fix confirm Add Token button order --- ui/app/add-token.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ui') diff --git a/ui/app/add-token.js b/ui/app/add-token.js index 9f1357591..bb34f5d00 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -295,12 +295,12 @@ AddTokenScreen.prototype.renderConfirmation = function () { ]), ]), h('div.add-token__buttons', [ - h('button.btn-secondary', { - onClick: () => addTokens(tokens).then(goHome), - }, 'Add Tokens'), - h('button.btn-tertiary', { + h('button.btn-cancel.add-token__button', { onClick: () => this.setState({ isShowingConfirmation: false }), }, 'Back'), + h('button.btn-clear.add-token__button', { + onClick: () => addTokens(tokens).then(goHome), + }, 'Add Tokens'), ]), ]) ) -- cgit From d5c311b13e6a9399252c4617b07ad463f6ead9b0 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Sun, 14 Jan 2018 13:56:54 -0800 Subject: add a loading spinner to conf-tx view --- ui/app/conf-tx.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui') diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index cb1afedfe..ce4d153b5 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -4,6 +4,7 @@ const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('./actions') const NetworkIndicator = require('./components/network') +const LoadingIndicator = require('./components/loading') const txHelper = require('../lib/tx-helper') const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification') @@ -60,6 +61,11 @@ ConfirmTxScreen.prototype.render = function () { h('.flex-column.flex-grow', [ + h(LoadingIndicator, { + isLoading: txData.loadingDefaults, + loadingMessage: 'Estimating transaction cost…', + }), + // subtitle and nav h('.section-title.flex-row.flex-center', [ !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { -- cgit From 27cbfa44c36830ea05e4d8f15d59c9e46564f0b7 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Sun, 14 Jan 2018 21:30:12 -0800 Subject: Move blockies option to the bottom of Settings --- ui/app/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/settings.js b/ui/app/settings.js index a3dd65f14..686e31bb9 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -256,13 +256,13 @@ class Settings extends Component { return ( h('div.settings__content', [ warning && h('div.settings__error', warning), - this.renderBlockieOptIn(), this.renderCurrentConversion(), // this.renderCurrentProvider(), this.renderNewRpcUrl(), this.renderStateLogs(), this.renderSeedWords(), !isMascara && this.renderOldUI(), + this.renderBlockieOptIn(), ]) ) } -- cgit From aa833a09281960bfc0af5032034021c25c26a7fd Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 15 Jan 2018 17:53:44 -0330 Subject: [NewUI] Place all users of extension into old UI (disable auto adding). (#2946) * Place all users of extension into old UI (disable auto adding). * Fix lint errors. --- ui/app/select-app.js | 53 +++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'ui') diff --git a/ui/app/select-app.js b/ui/app/select-app.js index ac6867aeb..193c98353 100644 --- a/ui/app/select-app.js +++ b/ui/app/select-app.js @@ -9,13 +9,13 @@ const { setFeatureFlag, setNetworkEndpoints } = require('./actions') const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums function mapStateToProps (state) { - return { - betaUI: state.metamask.featureFlags.betaUI, - autoAdd: autoAddToBetaUI(state), - isUnlocked: state.metamask.isUnlocked, - isMascara: state.metamask.isMascara, - firstTime: Object.keys(state.metamask.identities).length === 0, - } + return { + betaUI: state.metamask.featureFlags.betaUI, + autoAdd: autoAddToBetaUI(state), + isUnlocked: state.metamask.isUnlocked, + isMascara: state.metamask.isMascara, + firstTime: Object.keys(state.metamask.identities).length === 0, + } } function mapDispatchToProps (dispatch) { @@ -34,28 +34,35 @@ module.exports = connect(mapStateToProps, mapDispatchToProps)(SelectedApp) inherits(SelectedApp, Component) function SelectedApp () { - Component.call(this) + Component.call(this) } SelectedApp.prototype.componentWillReceiveProps = function (nextProps) { - const { - isUnlocked, - setFeatureFlagWithModal, - setFeatureFlagWithoutModal, - isMascara, - firstTime, - } = this.props - - if (isMascara || firstTime) { - setFeatureFlagWithoutModal() - } else if (!isUnlocked && nextProps.isUnlocked && (nextProps.autoAdd)) { - setFeatureFlagWithModal() - } + // Code commented out until we begin auto adding users to NewUI + const { + // isUnlocked, + // setFeatureFlagWithModal, + setFeatureFlagWithoutModal, + isMascara, + // firstTime, + } = this.props + + // if (isMascara || firstTime) { + if (isMascara) { + setFeatureFlagWithoutModal() + } + // } else if (!isUnlocked && nextProps.isUnlocked && (nextProps.autoAdd)) { + // setFeatureFlagWithModal() + // } } SelectedApp.prototype.render = function () { - const { betaUI, isMascara, firstTime } = this.props + // Code commented out until we begin auto adding users to NewUI + // const { betaUI, isMascara, firstTime } = this.props + // const Selected = betaUI || isMascara || firstTime ? App : OldApp + + const { betaUI, isMascara } = this.props + const Selected = betaUI || isMascara ? App : OldApp - const Selected = betaUI || isMascara || firstTime ? App : OldApp return h(Selected) } -- cgit From 58be1742e1fbfc6ae73e50256849f2e673989446 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 15 Jan 2018 16:04:49 -0800 Subject: Rename lock to log out Fixes #2475 --- ui/app/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/app.js b/ui/app/app.js index bc198b482..f0dfef34f 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -395,7 +395,7 @@ App.prototype.renderDropdown = function () { h(DropdownMenuItem, { closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }), onClick: () => { this.props.dispatch(actions.lockMetamask()) }, - }, 'Lock'), + }, 'Log Out'), h(DropdownMenuItem, { closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }), -- cgit From 644adeccf6b5365ef2c8c9a5ba69b90fdaa1f2ec Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Sat, 13 Jan 2018 14:59:16 -0800 Subject: Fix Hide Token modal styling, popup positioning --- .../modals/hide-token-confirmation-modal.js | 4 ++-- ui/app/css/itcss/components/modal.scss | 24 +++++++--------------- ui/app/css/itcss/components/newui-sections.scss | 2 +- ui/app/css/itcss/components/token-list.scss | 10 ++++----- 4 files changed, 15 insertions(+), 25 deletions(-) (limited to 'ui') diff --git a/ui/app/components/modals/hide-token-confirmation-modal.js b/ui/app/components/modals/hide-token-confirmation-modal.js index fa3ad0b1e..56c7ba299 100644 --- a/ui/app/components/modals/hide-token-confirmation-modal.js +++ b/ui/app/components/modals/hide-token-confirmation-modal.js @@ -58,12 +58,12 @@ HideTokenConfirmationModal.prototype.render = function () { ]), h('div.hide-token-confirmation__buttons', {}, [ - h('button.btn-clear', { + h('button.btn-cancel.hide-token-confirmation__button', { onClick: () => hideModal(), }, [ 'CANCEL', ]), - h('button.btn-clear', { + h('button.btn-clear.hide-token-confirmation__button', { onClick: () => hideToken(address), }, [ 'HIDE', diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss index 7a2ec35a4..501351700 100644 --- a/ui/app/css/itcss/components/modal.scss +++ b/ui/app/css/itcss/components/modal.scss @@ -486,10 +486,9 @@ .hide-token-confirmation { min-height: 250.72px; - width: 374.49px; border-radius: 4px; - background-color: #FFFFFF; - box-shadow: 0 1px 7px 0 rgba(0,0,0,0.5); + background-color: $white; + box-shadow: 0 1px 7px 0 rgba(0, 0, 0, .5); &__container { padding: 24px 27px 21px; @@ -499,7 +498,7 @@ } &__identicon { - margin-bottom: 10px + margin-bottom: 10px; } &__symbol { @@ -538,20 +537,11 @@ justify-content: center; margin-top: 15px; width: 100%; + } - button { - height: 44px; - width: 113px; - border: 1px solid $scorpion; - border-radius: 2px; - color: $tundora; - font-family: Roboto; - font-size: 14px; - line-height: 20px; - text-align: center; - margin-left: 4px; - margin-right: 4px; - } + &__button { + width: 141px; + margin: 0 5px; } } diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index af1a6974c..c9a06a2cc 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -153,7 +153,7 @@ $wallet-view-bg: $alabaster; background: rgb(250, 250, 250); z-index: $sidebar-z-index; position: fixed; - top: 56px; + top: 66px; left: 0; right: 0; bottom: 0; diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index bdd26099a..e24bf812b 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -63,11 +63,11 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( height: 55px; width: 191px; border-radius: 4px; - background-color: rgba(0,0,0,0.82); - box-shadow: 0 2px 4px 0 rgba(0,0,0,0.5); - position: fixed; - margin-top: 20px; - margin-left: 105px; + background-color: rgba(0, 0, 0, .82); + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5); + position: absolute; + top: 60px; + right: 25px; z-index: 2000; &__close-area { -- cgit From baebf64afd594316a4e160ff1d046ea68bfc5c70 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 15 Jan 2018 14:37:59 -0800 Subject: Fix send screen value input --- ui/app/components/currency-input.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js index 66880091f..6f7862e51 100644 --- a/ui/app/components/currency-input.js +++ b/ui/app/components/currency-input.js @@ -50,10 +50,18 @@ function sanitizeValue (value) { CurrencyInput.prototype.handleChange = function (newValue) { const { onInputChange } = this.props + const { value } = this.state - this.setState({ value: sanitizeValue(newValue) }) + let parsedValue = newValue + const newValueLastIndex = newValue.length - 1 - onInputChange(sanitizeValue(newValue)) + if (value === '0' && newValue[newValueLastIndex] === '0') { + parsedValue = parsedValue.slice(0, newValueLastIndex) + } + + const sanitizedValue = sanitizeValue(parsedValue) + this.setState({ value: sanitizedValue }) + onInputChange(sanitizedValue) } // If state.value === props.value plus a decimal point, or at least one @@ -90,6 +98,6 @@ CurrencyInput.prototype.render = function () { size: valueToRender.length * inputSizeMultiplier, readOnly, onChange: e => this.handleChange(e.target.value), - ref: inputRef, + ref: inputRef, }) } -- cgit From a4fd4f013fc0657920a452f04591dc26d4a5639e Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 15 Jan 2018 22:11:06 -0330 Subject: Restore display of all unconfirmed transactions. --- ui/app/reducers/app.js | 68 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'ui') diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index b4950e9d9..c3ade5cdc 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -389,7 +389,7 @@ function reduceApp (state, action) { return extend(appState, { currentView: { name: 'confTx', - context: action.id ? indexForPending(state, action.id) : indexForLastPending(state), + context: action.id ? indexForPending(state, action.id) : 0, }, transForward: action.transForward, warning: null, @@ -409,36 +409,36 @@ function reduceApp (state, action) { case actions.COMPLETED_TX: log.debug('reducing COMPLETED_TX for tx ' + action.value) - // const otherUnconfActions = getUnconfActionList(state) - // .filter(tx => tx.id !== action.value) - // const hasOtherUnconfActions = otherUnconfActions.length > 0 - - // if (hasOtherUnconfActions) { - // log.debug('reducer detected txs - rendering confTx view') - // return extend(appState, { - // transForward: false, - // currentView: { - // name: 'confTx', - // context: 0, - // }, - // warning: null, - // }) - // } else { - log.debug('attempting to close popup') - return extend(appState, { - // indicate notification should close - shouldClose: true, - transForward: false, - warning: null, - currentView: { - name: 'accountDetail', - context: state.metamask.selectedAddress, - }, - accountDetail: { - subview: 'transactions', - }, - }) - // } + const otherUnconfActions = getUnconfActionList(state) + .filter(tx => tx.id !== action.value) + const hasOtherUnconfActions = otherUnconfActions.length > 0 + + if (hasOtherUnconfActions) { + log.debug('reducer detected txs - rendering confTx view') + return extend(appState, { + transForward: false, + currentView: { + name: 'confTx', + context: 0, + }, + warning: null, + }) + } else { + log.debug('attempting to close popup') + return extend(appState, { + // indicate notification should close + shouldClose: true, + transForward: false, + warning: null, + currentView: { + name: 'accountDetail', + context: state.metamask.selectedAddress, + }, + accountDetail: { + subview: 'transactions', + }, + }) + } case actions.NEXT_TX: return extend(appState, { @@ -679,6 +679,6 @@ function indexForPending (state, txId) { return index } -function indexForLastPending (state) { - return getUnconfActionList(state).length -} +// function indexForLastPending (state) { +// return getUnconfActionList(state).length +// } -- cgit From d7a1019a2cda83b263b21d35e0f776e8f76d8998 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Tue, 16 Jan 2018 16:44:03 -0330 Subject: Adding one or more tokens sets the selected token before returning the user to the main screen. (#2995) --- ui/app/actions.js | 3 +++ ui/app/util.js | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 192a73f76..25cb2c23f 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1,5 +1,6 @@ const abi = require('human-standard-token-abi') const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url') +const { getTokenAddressFromTokenObject } = require('./util') const ethUtil = require('ethereumjs-util') var actions = { @@ -1094,10 +1095,12 @@ function removeToken (address) { function addTokens (tokens) { return dispatch => { if (Array.isArray(tokens)) { + dispatch(actions.setSelectedToken(getTokenAddressFromTokenObject(tokens[0]))) return Promise.all(tokens.map(({ address, symbol, decimals }) => ( dispatch(addToken(address, symbol, decimals)) ))) } else { + dispatch(actions.setSelectedToken(getTokenAddressFromTokenObject(tokens))) return Promise.all( Object .entries(tokens) diff --git a/ui/app/util.js b/ui/app/util.js index 70c503550..800ccb218 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -56,6 +56,7 @@ module.exports = { exportAsFile: exportAsFile, isInvalidChecksumAddress, allNull, + getTokenAddressFromTokenObject, } function valuesFor (obj) { @@ -281,3 +282,7 @@ function exportAsFile (filename, data) { function allNull (obj) { return Object.entries(obj).every(([key, value]) => value === null) } + +function getTokenAddressFromTokenObject (token) { + return Object.values(token)[0].address.toLowerCase() +} -- cgit From 668aab11d1aa94111252fee3d2abd20c207be71b Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Tue, 16 Jan 2018 16:45:18 -0330 Subject: Vertically centers the text of the new ui modal header. (#2987) --- ui/app/css/itcss/components/modal.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'ui') diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss index 501351700..5bca4a07d 100644 --- a/ui/app/css/itcss/components/modal.scss +++ b/ui/app/css/itcss/components/modal.scss @@ -815,6 +815,7 @@ width: 100%; display: flex; justify-content: center; + align-items: center; padding: 30px; font-size: 22px; color: $nile-blue; -- cgit From ccb80594be3000488b7c73f9fd5e56168e0d5042 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 16 Jan 2018 16:08:42 -0800 Subject: Readjust gas fees when switching networks on the send screen --- ui/app/components/send/send-v2-container.js | 1 + ui/app/send-v2.js | 65 +++++++++++++++++++---------- 2 files changed, 44 insertions(+), 22 deletions(-) (limited to 'ui') diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js index 2d2ed4546..1106902b7 100644 --- a/ui/app/components/send/send-v2-container.js +++ b/ui/app/components/send/send-v2-container.js @@ -51,6 +51,7 @@ function mapStateToProps (state) { amountConversionRate: selectedToken ? tokenToFiatRate : conversionRate, tokenContract: getSelectedTokenContract(state), unapprovedTxs: state.metamask.unapprovedTxs, + network: state.metamask.network, } } diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index ca73fa5ea..d9187fd80 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -85,6 +85,20 @@ SendTransactionScreen.prototype.componentWillMount = function () { const { updateTokenExchangeRate, selectedToken = {}, + } = this.props + + const { symbol } = selectedToken || {} + + if (symbol) { + updateTokenExchangeRate(symbol) + } + + this.updateGas() +} + +SendTransactionScreen.prototype.updateGas = function () { + const { + selectedToken = {}, getGasPrice, estimateGas, selectedAddress, @@ -96,17 +110,16 @@ SendTransactionScreen.prototype.componentWillMount = function () { gasPrice, gasLimit, } = this.props - const { symbol } = selectedToken || {} - if (symbol) { - updateTokenExchangeRate(symbol) - } + const { symbol } = selectedToken || {} - const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data) + const tokenBalancePromise = tokenContract + ? tokenContract.balanceOf(from.address) + : Promise.resolve() - const tokenBalancePromise = tokenContract && tokenContract.balanceOf(from.address) - let newGasTotal if (!editingTransactionId) { + const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data) + Promise .all([ getGasPrice(), @@ -114,27 +127,26 @@ SendTransactionScreen.prototype.componentWillMount = function () { tokenBalancePromise, ]) .then(([gasPrice, gas, usersToken]) => { - - const newGasTotal = multiplyCurrencies(gas, gasPrice, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, - }) + const newGasTotal = this.getGasTotal(gas, gasPrice) updateGasTotal(newGasTotal) this.updateSendTokenBalance(usersToken) }) } else { - newGasTotal = multiplyCurrencies(gasLimit, gasPrice, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, - }) + const newGasTotal = this.getGasTotal(gasLimit, gasPrice) updateGasTotal(newGasTotal) - tokenBalancePromise && tokenBalancePromise.then( - usersToken => this.updateSendTokenBalance(usersToken)) + tokenBalancePromise + .then(usersToken => this.updateSendTokenBalance(usersToken)) } } +SendTransactionScreen.prototype.getGasTotal = function (gasLimit, gasPrice) { + return multiplyCurrencies(gasLimit, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) +} + SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) { const { from: { balance }, @@ -142,11 +154,14 @@ SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) { tokenBalance, amount, selectedToken, + network, } = this.props + const { from: { balance: prevBalance }, gasTotal: prevGasTotal, tokenBalance: prevTokenBalance, + network: prevNetwork, } = prevProps const notFirstRender = [prevBalance, prevGasTotal].every(n => n !== null) @@ -156,8 +171,14 @@ SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) { const tokenBalanceHasChanged = selectedToken && tokenBalance !== prevTokenBalance const amountValidationChange = balanceHasChanged || gasTotalHasChange || tokenBalanceHasChanged - if (notFirstRender && amountValidationChange) { - this.validateAmount(amount) + if (notFirstRender) { + if (amountValidationChange) { + this.validateAmount(amount) + } + + if (network !== prevNetwork && network !== 'loading') { + this.updateGas() + } } } -- cgit From 65e9d9efc56a99ecd3a46b98ed58af9604374f68 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 16 Jan 2018 17:41:42 -0800 Subject: Fix rendering QR code in old UI, hide unnecessary back button --- ui/app/components/modals/deposit-ether-modal.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js index 3e6d3fde1..532d66653 100644 --- a/ui/app/components/modals/deposit-ether-modal.js +++ b/ui/app/components/modals/deposit-ether-modal.js @@ -62,6 +62,7 @@ DepositEtherModal.prototype.renderRow = function ({ hideButton, hideTitle, onBackClick, + showBackButton, }) { if (hide) { return null @@ -71,7 +72,7 @@ DepositEtherModal.prototype.renderRow = function ({ className: className || 'deposit-ether-modal__buy-row', }, [ - h('div.deposit-ether-modal__buy-row__back', { + onBackClick && showBackButton && h('div.deposit-ether-modal__buy-row__back', { onClick: onBackClick, }, [ @@ -167,6 +168,7 @@ DepositEtherModal.prototype.render = function () { hideButton: buyingWithShapeshift, hideTitle: buyingWithShapeshift, onBackClick: () => this.setState({ buyingWithShapeshift: false }), + showBackButton: this.state.buyingWithShapeshift, className: buyingWithShapeshift && 'deposit-ether-modal__buy-row__shapeshift-buy', }), -- cgit From 40e58d31326cc4e759991d15e7e84140e483a791 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 16 Jan 2018 11:58:02 -0800 Subject: Fix tx-list, confirmation screen styling --- ui/app/components/tx-list.js | 9 ++++----- ui/app/css/itcss/components/confirm.scss | 17 +++++++++-------- ui/app/css/itcss/components/hero-balance.scss | 1 + ui/app/css/itcss/components/transaction-list.scss | 4 ++++ 4 files changed, 18 insertions(+), 13 deletions(-) (limited to 'ui') diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js index 50e328dac..84cd0f093 100644 --- a/ui/app/components/tx-list.js +++ b/ui/app/components/tx-list.js @@ -36,16 +36,15 @@ TxList.prototype.componentWillMount = function () { } TxList.prototype.render = function () { - return h('div.flex-column.tx-list-container', {}, [ - + return h('div.flex-column', [ h('div.flex-row.tx-list-header-wrapper', [ h('div.flex-row.tx-list-header', [ h('div', 'transactions'), ]), ]), - - this.renderTransaction(), - + h('div.flex-column.tx-list-container', {}, [ + this.renderTransaction(), + ]), ]) } diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss index e75a827f9..255f66e66 100644 --- a/ui/app/css/itcss/components/confirm.scss +++ b/ui/app/css/itcss/components/confirm.scss @@ -2,13 +2,15 @@ position: relative; align-items: center; font-family: Roboto; - flex: 0 0 auto; + flex: 1 0 auto; flex-flow: column nowrap; box-shadow: 0 2px 4px 0 rgba($black, .08); border-radius: 8px; + display: flex; @media screen and (max-width: 575px) { width: 100%; + box-shadow: initial; } @media screen and (min-width: 576px) { @@ -272,8 +274,8 @@ section .confirm-screen-account-number, } .confirm-screen-confirm-button { - height: 62px; - border-radius: 2px; + height: 50px; + border-radius: 4px; background-color: #02c9b1; font-size: 16px; color: $white; @@ -285,11 +287,11 @@ section .confirm-screen-account-number, box-shadow: none; flex: 1 0 auto; font-weight: 300; - margin: 0 8px; + margin: 0 5px; } .btn-light.confirm-screen-cancel-button { - height: 62px; + height: 50px; background: none; border: none; opacity: 1; @@ -298,12 +300,11 @@ section .confirm-screen-account-number, padding-top: 15px; padding-bottom: 15px; font-size: 16px; - line-height: 32px; box-shadow: none; cursor: pointer; flex: 1 0 auto; font-weight: 300; - margin: 0 8px; + margin: 0 5px; } #pending-tx-form { @@ -312,7 +313,7 @@ section .confirm-screen-account-number, display: flex; flex-flow: row nowrap; background-color: $white; - padding: 12px 18px; + padding: 12px; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; width: 100%; diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss index 99fd2a96d..ccc9a0118 100644 --- a/ui/app/css/itcss/components/hero-balance.scss +++ b/ui/app/css/itcss/components/hero-balance.scss @@ -17,6 +17,7 @@ justify-content: flex-start; align-items: center; margin: 2.3em 2.37em .8em; + flex: 0 0 auto; } .balance-container { diff --git a/ui/app/css/itcss/components/transaction-list.scss b/ui/app/css/itcss/components/transaction-list.scss index 19dadc69a..29001a842 100644 --- a/ui/app/css/itcss/components/transaction-list.scss +++ b/ui/app/css/itcss/components/transaction-list.scss @@ -6,6 +6,10 @@ } } +.tx-list-header-wrapper { + flex: 0 0 auto; +} + .tx-list-header { text-transform: capitalize; } -- cgit From fdaf6eacb2dc6cbd6941dd7debdd5cd89fca4672 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Jan 2018 17:29:25 -0330 Subject: Show now tokens by default and improve search on add token screen. --- ui/app/add-token.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/app/add-token.js b/ui/app/add-token.js index bb34f5d00..e3fe93362 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -3,6 +3,7 @@ const Component = require('react').Component const classnames = require('classnames') const h = require('react-hyperscript') const connect = require('react-redux').connect +const R = require('ramda'); const Fuse = require('fuse.js') const contractMap = require('eth-contract-metadata') const TokenBalance = require('./components/token-balance') @@ -17,12 +18,14 @@ const fuse = new Fuse(contractList, { distance: 100, maxPatternLength: 32, minMatchCharLength: 1, - keys: ['address', 'name', 'symbol'], + keys: [ + { name: 'name', weight: 0.5 }, + { name: 'symbol', weight: 0.5 }, + ], }) const actions = require('./actions') const ethUtil = require('ethereumjs-util') const { tokenInfoGetter } = require('./token-util') -const R = require('ramda') const emptyAddr = '0x0000000000000000000000000000000000000000' @@ -217,9 +220,11 @@ AddTokenScreen.prototype.renderCustomForm = function () { AddTokenScreen.prototype.renderTokenList = function () { const { searchQuery = '', selectedTokens } = this.state - const results = searchQuery - ? fuse.search(searchQuery) || [] - : contractList + const fuseSearchResult = fuse.search(searchQuery) + const addressSearchResult = contractList.filter(token => { + return token.address.toLowerCase() === searchQuery.toLowerCase() + }) + const results = [...addressSearchResult, ...fuseSearchResult] return Array(6).fill(undefined) .map((_, i) => { -- cgit From f8bf8cb527ae0e24ccf9d1c9f2f6baa457f2e659 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 17 Jan 2018 17:37:18 -0800 Subject: Update popout to fullscreen icon --- ui/app/components/tx-view.js | 4 ++-- ui/app/css/itcss/components/newui-sections.scss | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js index 0148b32a5..b25d8e0f9 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -100,7 +100,7 @@ TxView.prototype.render = function () { h('div.flex-row.phone-visible', { style: { - margin: '1em 0.9em', + margin: '1.5em 1.2em 0', justifyContent: 'space-between', alignItems: 'center', }, @@ -136,7 +136,7 @@ TxView.prototype.render = function () { !isMascara && h('div.open-in-browser', { onClick: () => global.platform.openExtensionInBrowser(), - }, [h('img', { src: 'images/open.svg' })]), + }, [h('img', { src: 'images/popout.svg' })]), ]), diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index c9a06a2cc..1c26882b5 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -40,6 +40,8 @@ $wallet-view-bg: $alabaster; .open-in-browser { cursor: pointer; + display: flex; + justify-content: center; } // wallet view and sidebar -- cgit From 853e7f84204226b9cc35fe8bca5cb6ebe7ff03b0 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 17 Jan 2018 18:50:18 -0800 Subject: Fix lint errors --- ui/app/add-token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/add-token.js b/ui/app/add-token.js index e3fe93362..3a806d34b 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -3,7 +3,7 @@ const Component = require('react').Component const classnames = require('classnames') const h = require('react-hyperscript') const connect = require('react-redux').connect -const R = require('ramda'); +const R = require('ramda') const Fuse = require('fuse.js') const contractMap = require('eth-contract-metadata') const TokenBalance = require('./components/token-balance') -- cgit From 4fae461a672b89a16c496d09321f11f86b873e32 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 18 Jan 2018 01:17:01 -0330 Subject: [NewUI] Send screen gas loading fixes (#3027) * Allow entering amount, but disable validation of amount, opening of gas customizer or clicking of next, when gas loading in send. * Fix variable name. --- ui/app/components/send/gas-fee-display-v2.js | 3 +- ui/app/css/itcss/components/send.scss | 2 +- ui/app/send-v2.js | 47 +++++++++++++--------------- 3 files changed, 25 insertions(+), 27 deletions(-) (limited to 'ui') diff --git a/ui/app/components/send/gas-fee-display-v2.js b/ui/app/components/send/gas-fee-display-v2.js index 806c33f0a..0c4c3f7a9 100644 --- a/ui/app/components/send/gas-fee-display-v2.js +++ b/ui/app/components/send/gas-fee-display-v2.js @@ -32,8 +32,9 @@ GasFeeDisplay.prototype.render = function () { }) : h('div.currency-display', 'Loading...'), - h('div.send-v2__sliders-icon-container', { + h('button.send-v2__sliders-icon-container', { onClick, + disabled: !gasTotal, }, [ h('i.fa.fa-sliders.send-v2__sliders-icon'), ]), diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index beb3e519c..7a6e2823b 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -652,11 +652,11 @@ border: 1px solid $curious-blue; border-radius: 4px; background-color: $white; - padding: 5px; position: absolute; right: 15px; top: 14px; cursor: pointer; + font-size: 1em; } &__sliders-icon { diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index d9187fd80..897caf16e 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -13,7 +13,6 @@ const MemoTextArea = require('./components/send/memo-textarea') const GasFeeDisplay = require('./components/send/gas-fee-display-v2') const { - MIN_GAS_TOTAL, TOKEN_TRANSFER_FUNCTION_SIGNATURE, } = require('./components/send/send-constants') @@ -116,6 +115,8 @@ SendTransactionScreen.prototype.updateGas = function () { const tokenBalancePromise = tokenContract ? tokenContract.balanceOf(from.address) : Promise.resolve() + tokenBalancePromise + .then(usersToken => this.updateSendTokenBalance(usersToken)) if (!editingTransactionId) { const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data) @@ -124,18 +125,14 @@ SendTransactionScreen.prototype.updateGas = function () { .all([ getGasPrice(), estimateGas(estimateGasParams), - tokenBalancePromise, ]) - .then(([gasPrice, gas, usersToken]) => { + .then(([gasPrice, gas]) => { const newGasTotal = this.getGasTotal(gas, gasPrice) updateGasTotal(newGasTotal) - this.updateSendTokenBalance(usersToken) }) } else { const newGasTotal = this.getGasTotal(gasLimit, gasPrice) updateGasTotal(newGasTotal) - tokenBalancePromise - .then(usersToken => this.updateSendTokenBalance(usersToken)) } } @@ -164,14 +161,14 @@ SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) { network: prevNetwork, } = prevProps - const notFirstRender = [prevBalance, prevGasTotal].every(n => n !== null) + const uninitialized = [prevBalance, prevGasTotal].every(n => n === null) const balanceHasChanged = balance !== prevBalance const gasTotalHasChange = gasTotal !== prevGasTotal const tokenBalanceHasChanged = selectedToken && tokenBalance !== prevTokenBalance const amountValidationChange = balanceHasChanged || gasTotalHasChange || tokenBalanceHasChanged - if (notFirstRender) { + if (!uninitialized) { if (amountValidationChange) { this.validateAmount(amount) } @@ -381,14 +378,19 @@ SendTransactionScreen.prototype.validateAmount = function (value) { const amount = value let amountError = null - const sufficientBalance = isBalanceSufficient({ - amount: selectedToken ? '0x0' : amount, - gasTotal, - balance, - primaryCurrency, - amountConversionRate, - conversionRate, - }) + + let sufficientBalance = true + + if (gasTotal) { + sufficientBalance = isBalanceSufficient({ + amount: selectedToken ? '0x0' : amount, + gasTotal, + balance, + primaryCurrency, + amountConversionRate, + conversionRate, + }) + } let sufficientTokens if (selectedToken) { @@ -404,7 +406,7 @@ SendTransactionScreen.prototype.validateAmount = function (value) { { value: amount, fromNumericBase: 'hex' }, ) - if (!sufficientBalance) { + if (conversionRate && !sufficientBalance) { amountError = 'Insufficient funds.' } else if (selectedToken && !sufficientTokens) { amountError = 'Insufficient tokens.' @@ -461,7 +463,7 @@ SendTransactionScreen.prototype.renderGasRow = function () { conversionRate, convertedCurrency, showCustomizeGasModal, - gasTotal = MIN_GAS_TOTAL, + gasTotal, } = this.props return h('div.send-v2__form-row', [ @@ -477,12 +479,6 @@ SendTransactionScreen.prototype.renderGasRow = function () { onClick: showCustomizeGasModal, }), - h('div.send-v2__sliders-icon-container', { - onClick: showCustomizeGasModal, - }, [ - h('i.fa.fa-sliders.send-v2__sliders-icon'), - ]), - ]), ]) @@ -533,6 +529,7 @@ SendTransactionScreen.prototype.renderFooter = function () { const { goHome, clearSend, + gasTotal, errors: { amount: amountError, to: toError }, } = this.props @@ -546,7 +543,7 @@ SendTransactionScreen.prototype.renderFooter = function () { }, }, 'Cancel'), h('button.btn-clear.send-v2__next-btn', { - disabled: !noErrors, + disabled: !noErrors || !gasTotal, onClick: event => this.onSubmit(event), }, 'Next'), ]) -- cgit From b05d21b1ba308bdb5b758d53dd79593a7a2bf26e Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 17 Jan 2018 20:08:29 -0800 Subject: Fix transaction list font sizes, padding --- ui/app/components/tx-list-item.js | 6 +----- ui/app/css/itcss/components/transaction-list.scss | 18 ++++++------------ 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'ui') diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js index 8a9253d4d..7ccc5c315 100644 --- a/ui/app/components/tx-list-item.js +++ b/ui/app/components/tx-list-item.js @@ -234,11 +234,7 @@ TxListItem.prototype.render = function () { style: {}, }, [ - h('span', { - className: classnames('tx-list-value', { - 'tx-list-value--confirmed': transactionStatus === 'confirmed', - }), - }, total), + h('span.tx-list-value', total), showFiatTotal && h('span.tx-list-fiat-value', fiatTotal), diff --git a/ui/app/css/itcss/components/transaction-list.scss b/ui/app/css/itcss/components/transaction-list.scss index 29001a842..c3df493df 100644 --- a/ui/app/css/itcss/components/transaction-list.scss +++ b/ui/app/css/itcss/components/transaction-list.scss @@ -73,7 +73,7 @@ } @media screen and (min-width: $break-large) { - padding-bottom: 12px; + padding-bottom: 8px; } } @@ -91,21 +91,13 @@ } .tx-list-date-wrapper { + margin-top: 6px; flex: 1 1 auto; - - @media screen and (max-width: $break-small) { - margin-top: 6px; - } - - @media screen and (min-width: $break-large) { - margin-top: 12px; - } } .tx-list-content-wrapper { align-items: stretch; margin-bottom: 4px; - margin-top: 2px; flex: 1 0 auto; width: 100%; display: flex; @@ -115,7 +107,7 @@ font-size: 12px; .tx-list-status { - font-size: 14px !important; + font-size: 12px !important; } .tx-list-account { @@ -129,7 +121,7 @@ .tx-list-fiat-value { font-size: 12px; - line-height: 16px; + line-height: 22px; } } } @@ -259,6 +251,8 @@ } .tx-list-fiat-value { + font-size: 12px; + line-height: initial; text-align: right; text-overflow: ellipsis; white-space: nowrap; -- cgit