From a7b7c8f0349ac8db16f264268745fd4b14e89422 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 28 May 2018 23:34:40 -0700 Subject: newui - unlock - dont catch errors unrelated to tryUnlockMetamask --- ui/app/components/pages/unlock-page/unlock-page.component.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pages/unlock-page/unlock-page.component.js b/ui/app/components/pages/unlock-page/unlock-page.component.js index a2f009d8f..b6384b32d 100644 --- a/ui/app/components/pages/unlock-page/unlock-page.component.js +++ b/ui/app/components/pages/unlock-page/unlock-page.component.js @@ -37,8 +37,8 @@ class UnlockPage extends Component { tryUnlockMetamask (password) { const { tryUnlockMetamask, history } = this.props tryUnlockMetamask(password) - .then(() => history.push(DEFAULT_ROUTE)) .catch(({ message }) => this.setState({ error: message })) + .then(() => history.push(DEFAULT_ROUTE)) } handleSubmit (event) { @@ -55,8 +55,8 @@ class UnlockPage extends Component { this.setState({ error: null }) tryUnlockMetamask(password) - .then(() => history.push(DEFAULT_ROUTE)) .catch(({ message }) => this.setState({ error: message })) + .then(() => history.push(DEFAULT_ROUTE)) } handleInputChange ({ target }) { -- cgit From d1f5d8ccc663bdc379864e155f12f580af127e8c Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 29 May 2018 09:35:18 -0500 Subject: Fix text field labels of first time flow. Add text fields to storybook (#4389) --- .../components/text-field/text-field.component.js | 95 ++++++++++++---------- ui/app/components/text-field/text-field.stories.js | 29 +++++++ 2 files changed, 80 insertions(+), 44 deletions(-) (limited to 'ui') diff --git a/ui/app/components/text-field/text-field.component.js b/ui/app/components/text-field/text-field.component.js index b695a449a..2c72d8124 100644 --- a/ui/app/components/text-field/text-field.component.js +++ b/ui/app/components/text-field/text-field.component.js @@ -1,8 +1,15 @@ -import React, { Component } from 'react' +import React from 'react' import PropTypes from 'prop-types' import { withStyles } from '@material-ui/core/styles' import { default as MaterialTextField } from '@material-ui/core/TextField' +const inputLabelBase = { + transform: 'none', + transition: 'none', + position: 'initial', + color: '#5b5b5b', +} + const styles = { materialLabel: { '&$materialFocused': { @@ -46,57 +53,57 @@ const styles = { border: '1px solid #2f9ae0', }, }, + largeInputLabel: { + ...inputLabelBase, + fontSize: '1rem', + }, inputLabel: { + ...inputLabelBase, fontSize: '.75rem', - transform: 'none', - transition: 'none', - position: 'initial', - color: '#5b5b5b', }, } -class TextField extends Component { - static defaultProps = { - error: null, - } +const TextField = props => { + const { error, classes, material, startAdornment, largeLabel, ...textFieldProps } = props - static propTypes = { - error: PropTypes.string, - classes: PropTypes.object, - material: PropTypes.bool, - startAdornment: PropTypes.element, - } + return ( + + ) +} - render () { - const { error, classes, material, startAdornment, ...textFieldProps } = this.props +TextField.defaultProps = { + error: null, +} - return ( - - ) - } +TextField.propTypes = { + error: PropTypes.string, + classes: PropTypes.object, + material: PropTypes.bool, + startAdornment: PropTypes.element, + largeLabel: PropTypes.bool, } export default withStyles(styles)(TextField) diff --git a/ui/app/components/text-field/text-field.stories.js b/ui/app/components/text-field/text-field.stories.js index ee3e5faaf..c00873b8a 100644 --- a/ui/app/components/text-field/text-field.stories.js +++ b/ui/app/components/text-field/text-field.stories.js @@ -22,3 +22,32 @@ storiesOf('TextField', module) error="Invalid value" /> ) + .add('Mascara text', () => + + ) + .add('Material text', () => + + ) + .add('Material password', () => + + ) + .add('Material error', () => + + ) -- cgit From e3c9629130901c2268350a58eb18f2ab9f6ab72e Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 29 May 2018 10:03:08 -0700 Subject: Fix add-token token list placeholder width (#4365) --- .../pages/add-token/token-list/token-list-placeholder/index.scss | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ui') diff --git a/ui/app/components/pages/add-token/token-list/token-list-placeholder/index.scss b/ui/app/components/pages/add-token/token-list/token-list-placeholder/index.scss index 9d0f4be32..cc495dfb0 100644 --- a/ui/app/components/pages/add-token/token-list/token-list-placeholder/index.scss +++ b/ui/app/components/pages/add-token/token-list/token-list-placeholder/index.scss @@ -11,6 +11,10 @@ width: 50%; text-align: center; margin-top: 8px; + + @media screen and (max-width: 575px) { + width: 60%; + } } &__link { -- cgit From 41e38fe5530bce1fd7d19060774179a215087fac Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 29 May 2018 10:23:06 -0700 Subject: Add notification for dropped retry transactions (#4363) --- ui/app/actions.js | 24 ++++++--- ui/app/app.js | 2 +- ui/app/components/index.scss | 2 + ui/app/components/modals/index.scss | 1 + ui/app/components/modals/modal.js | 35 +++++++++++- .../modals/transaction-confirmed/index.js | 2 + .../modals/transaction-confirmed/index.scss | 21 ++++++++ .../transaction-confirmed.component.js | 46 ++++++++++++++++ .../transaction-confirmed.container.js | 20 +++++++ ui/app/components/pending-tx/confirm-send-ether.js | 60 +++++++++++++-------- ui/app/components/pending-tx/confirm-send-token.js | 57 +++++++++++++++----- ui/app/components/tx-list-item.js | 10 +++- ui/app/conf-tx.js | 63 +++++++++++++++++----- ui/app/reducers/app.js | 19 ++++--- 14 files changed, 294 insertions(+), 68 deletions(-) create mode 100644 ui/app/components/modals/index.scss create mode 100644 ui/app/components/modals/transaction-confirmed/index.js create mode 100644 ui/app/components/modals/transaction-confirmed/index.scss create mode 100644 ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js create mode 100644 ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js (limited to 'ui') diff --git a/ui/app/actions.js b/ui/app/actions.js index 894e31fde..649f740e9 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1397,16 +1397,24 @@ function markAccountsFound () { function retryTransaction (txId) { log.debug(`background.retryTransaction`) + let newTxId + return (dispatch) => { - background.retryTransaction(txId, (err, newState) => { - if (err) { - return dispatch(actions.displayWarning(err.message)) - } - const { selectedAddressTxList } = newState - const { id: newTxId } = selectedAddressTxList[selectedAddressTxList.length - 1] - dispatch(actions.updateMetamaskState(newState)) - dispatch(actions.viewPendingTx(newTxId)) + return new Promise((resolve, reject) => { + background.retryTransaction(txId, (err, newState) => { + if (err) { + dispatch(actions.displayWarning(err.message)) + reject(err) + } + + const { selectedAddressTxList } = newState + const { id } = selectedAddressTxList[selectedAddressTxList.length - 1] + newTxId = id + resolve(newState) + }) }) + .then(newState => dispatch(actions.updateMetamaskState(newState))) + .then(() => newTxId) } } diff --git a/ui/app/app.js b/ui/app/app.js index 3d2961340..aa2b24422 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -76,7 +76,7 @@ class App extends Component { h(Authenticated, { path: REVEAL_SEED_ROUTE, exact, component: RevealSeedConfirmation }), h(Authenticated, { path: SETTINGS_ROUTE, component: Settings }), h(Authenticated, { path: NOTICE_ROUTE, exact, component: NoticeScreen }), - h(Authenticated, { path: CONFIRM_TRANSACTION_ROUTE, component: ConfirmTxScreen }), + h(Authenticated, { path: `${CONFIRM_TRANSACTION_ROUTE}/:id?`, component: ConfirmTxScreen }), h(Authenticated, { path: SEND_ROUTE, exact, component: SendTransactionScreen2 }), h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }), h(Authenticated, { path: CONFIRM_ADD_TOKEN_ROUTE, exact, component: ConfirmAddTokenPage }), diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index f3fe823f8..e69acff63 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -3,3 +3,5 @@ @import './info-box/index'; @import './pages/index'; + +@import './modals/index'; diff --git a/ui/app/components/modals/index.scss b/ui/app/components/modals/index.scss new file mode 100644 index 000000000..ec6207f7e --- /dev/null +++ b/ui/app/components/modals/index.scss @@ -0,0 +1 @@ +@import './transaction-confirmed/index'; diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 43dcd20ae..841189277 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -20,6 +20,7 @@ const HideTokenConfirmationModal = require('./hide-token-confirmation-modal') const CustomizeGasModal = require('../customize-gas-modal') const NotifcationModal = require('./notification-modal') const ConfirmResetAccount = require('./notification-modals/confirm-reset-account') +const TransactionConfirmed = require('./transaction-confirmed') const accountModalStyle = { mobileModalStyle: { @@ -265,6 +266,37 @@ const MODALS = { }, }, + TRANSACTION_CONFIRMED: { + disableBackdropClick: true, + contents: [ + h(TransactionConfirmed, {}, []), + ], + 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: '344px', + transform: 'translate3d(-50%, 0, 0px)', + top: '15%', + border: '1px solid #CCCFD1', + borderRadius: '8px', + backgroundColor: '#FFFFFF', + boxShadow: '0 2px 22px 0 rgba(0,0,0,0.2)', + }, + contentStyle: { + borderRadius: '8px', + height: '100%', + }, + }, + DEFAULT: { contents: [], mobileModalStyle: {}, @@ -306,7 +338,7 @@ module.exports = connect(mapStateToProps, mapDispatchToProps)(Modal) Modal.prototype.render = function () { const modal = MODALS[this.props.modalState.name || 'DEFAULT'] - const children = modal.contents + const { contents: children, disableBackdropClick = false } = modal const modalStyle = modal[isMobileView() ? 'mobileModalStyle' : 'laptopModalStyle'] const contentStyle = modal.contentStyle || {} @@ -326,6 +358,7 @@ Modal.prototype.render = function () { modalStyle, contentStyle, backdropStyle: BACKDROPSTYLE, + closeOnClick: !disableBackdropClick, }, children, ) diff --git a/ui/app/components/modals/transaction-confirmed/index.js b/ui/app/components/modals/transaction-confirmed/index.js new file mode 100644 index 000000000..c8db91388 --- /dev/null +++ b/ui/app/components/modals/transaction-confirmed/index.js @@ -0,0 +1,2 @@ +import TransactionConfirmed from './transaction-confirmed.container' +module.exports = TransactionConfirmed diff --git a/ui/app/components/modals/transaction-confirmed/index.scss b/ui/app/components/modals/transaction-confirmed/index.scss new file mode 100644 index 000000000..f8cd1f212 --- /dev/null +++ b/ui/app/components/modals/transaction-confirmed/index.scss @@ -0,0 +1,21 @@ +.transaction-confirmed { + display: flex; + flex-direction: column; + align-items: center; + padding: 32px; + + &__title { + font-size: 2rem; + padding: 16px 0; + } + + &__description { + text-align: center; + font-size: .875rem; + line-height: 1.5rem; + } + + @media screen and (max-width: 575px) { + justify-content: center; + } +} diff --git a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js new file mode 100644 index 000000000..8d3b288ae --- /dev/null +++ b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Button from '../../button' + +class TransactionConfirmed extends Component { + render () { + const { t } = this.context + + return ( +
+
+ +
+ { `${t('confirmed')}!` } +
+
+ { t('initialTransactionConfirmed') } +
+
+
+ +
+
+ ) + } +} + +TransactionConfirmed.propTypes = { + hideModal: PropTypes.func.isRequired, + onHide: PropTypes.func.isRequired, +} + +TransactionConfirmed.contextTypes = { + t: PropTypes.func, +} + +export default TransactionConfirmed diff --git a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js new file mode 100644 index 000000000..63872f7f2 --- /dev/null +++ b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux' +import TransactionConfirmed from './transaction-confirmed.component' + +const { hideModal } = require('../../../actions') + +const mapStateToProps = state => { + const { appState: { modal: { modalState: { props } } } } = state + const { onHide } = props + return { + onHide, + } +} + +const mapDispatchToProps = dispatch => { + return { + hideModal: () => dispatch(hideModal()), + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(TransactionConfirmed) diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index c07c96ccc..5ad35c269 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -291,18 +291,48 @@ ConfirmSendEther.prototype.convertToRenderableCurrency = function (value, curren : value } -ConfirmSendEther.prototype.editTransaction = function (txMeta) { +ConfirmSendEther.prototype.editTransaction = function () { const { editTransaction, history } = this.props + const txMeta = this.gatherTxMeta() editTransaction(txMeta) history.push(SEND_ROUTE) } -ConfirmSendEther.prototype.renderNetworkDisplay = function () { +ConfirmSendEther.prototype.renderHeaderRow = function (isTxReprice) { const windowType = window.METAMASK_UI_TYPE + const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION && + windowType !== ENVIRONMENT_TYPE_POPUP - return (windowType === ENVIRONMENT_TYPE_NOTIFICATION || windowType === ENVIRONMENT_TYPE_POPUP) - ? h(NetworkDisplay) - : null + if (isTxReprice && isFullScreen) { + return null + } + + return ( + h('.page-container__header-row', [ + h('span.page-container__back-button', { + onClick: () => this.editTransaction(), + style: { + visibility: isTxReprice ? 'hidden' : 'initial', + }, + }, 'Edit'), + !isFullScreen && h(NetworkDisplay), + ]) + ) +} + +ConfirmSendEther.prototype.renderHeader = function (isTxReprice) { + const title = isTxReprice ? this.context.t('speedUpTitle') : this.context.t('confirm') + const subtitle = isTxReprice + ? this.context.t('speedUpSubtitle') + : this.context.t('pleaseReviewTransaction') + + return ( + h('.page-container__header', [ + this.renderHeaderRow(isTxReprice), + h('.page-container__title', title), + h('.page-container__subtitle', subtitle), + ]) + ) } ConfirmSendEther.prototype.render = function () { @@ -320,6 +350,7 @@ ConfirmSendEther.prototype.render = function () { }, } = this.props const txMeta = this.gatherTxMeta() + const isTxReprice = Boolean(txMeta.lastGasPrice) const txParams = txMeta.txParams || {} const { @@ -338,11 +369,6 @@ ConfirmSendEther.prototype.render = function () { totalInETH, } = this.getData() - const title = txMeta.lastGasPrice ? 'Reprice Transaction' : 'Confirm' - const subtitle = txMeta.lastGasPrice - ? 'Increase your gas fee to attempt to overwrite and speed up your transaction' - : 'Please review your transaction.' - const convertedAmountInFiat = this.convertToRenderableCurrency(amountInFIAT, currentCurrency) const convertedTotalInFiat = this.convertToRenderableCurrency(totalInFIAT, currentCurrency) @@ -362,19 +388,7 @@ ConfirmSendEther.prototype.render = function () { return ( // Main Send token Card h('.page-container', [ - h('.page-container__header', [ - h('.page-container__header-row', [ - h('span.page-container__back-button', { - onClick: () => this.editTransaction(txMeta), - style: { - visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden', - }, - }, 'Edit'), - this.renderNetworkDisplay(), - ]), - h('.page-container__title', title), - h('.page-container__subtitle', subtitle), - ]), + this.renderHeader(isTxReprice), h('.page-container__content', [ h(SenderToRecipient, { senderName: fromName, diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index 656093b3d..ddaa13d22 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -12,6 +12,7 @@ const actions = require('../../actions') const clone = require('clone') const Identicon = require('../identicon') const GasFeeDisplay = require('../send/gas-fee-display-v2.js') +const NetworkDisplay = require('../network-display') const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const { @@ -39,6 +40,11 @@ const { } = require('../../selectors') const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes') +const { + ENVIRONMENT_TYPE_POPUP, + ENVIRONMENT_TYPE_NOTIFICATION, +} = require('../../../../app/scripts/lib/enums') + ConfirmSendToken.contextTypes = { t: PropTypes.func, } @@ -430,6 +436,43 @@ ConfirmSendToken.prototype.convertToRenderableCurrency = function (value, curren : value } +ConfirmSendToken.prototype.renderHeaderRow = function (isTxReprice) { + const windowType = window.METAMASK_UI_TYPE + const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION && + windowType !== ENVIRONMENT_TYPE_POPUP + + if (isTxReprice && isFullScreen) { + return null + } + + return ( + h('.page-container__header-row', [ + h('span.page-container__back-button', { + onClick: () => this.editTransaction(), + style: { + visibility: isTxReprice ? 'hidden' : 'initial', + }, + }, 'Edit'), + !isFullScreen && h(NetworkDisplay), + ]) + ) +} + +ConfirmSendToken.prototype.renderHeader = function (isTxReprice) { + const title = isTxReprice ? this.context.t('speedUpTitle') : this.context.t('confirm') + const subtitle = isTxReprice + ? this.context.t('speedUpSubtitle') + : this.context.t('pleaseReviewTransaction') + + return ( + h('.page-container__header', [ + this.renderHeaderRow(isTxReprice), + h('.page-container__title', title), + h('.page-container__subtitle', subtitle), + ]) + ) +} + ConfirmSendToken.prototype.render = function () { const txMeta = this.gatherTxMeta() const { @@ -443,25 +486,13 @@ ConfirmSendToken.prototype.render = function () { }, } = this.getData() - this.inputs = [] - const isTxReprice = Boolean(txMeta.lastGasPrice) - const title = isTxReprice ? this.context.t('reprice_title') : this.context.t('confirm') - const subtitle = isTxReprice - ? this.context.t('reprice_subtitle') - : this.context.t('pleaseReviewTransaction') return ( h('div.confirm-screen-container.confirm-send-token', [ // Main Send token Card h('div.page-container', [ - h('div.page-container__header', [ - !txMeta.lastGasPrice && h('button.confirm-screen-back-button', { - onClick: () => this.editTransaction(txMeta), - }, this.context.t('edit')), - h('div.page-container__title', title), - h('div.page-container__subtitle', subtitle), - ]), + this.renderHeader(isTxReprice), h('.page-container__content', [ h('div.flex-row.flex-center.confirm-screen-identicons', [ h('div.confirm-screen-account-wrapper', [ diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js index bd4ea80a6..ef441ff73 100644 --- a/ui/app/components/tx-list-item.js +++ b/ui/app/components/tx-list-item.js @@ -1,5 +1,7 @@ const Component = require('react').Component const PropTypes = require('prop-types') +const { compose } = require('recompose') +const { withRouter } = require('react-router-dom') const h = require('react-hyperscript') const connect = require('react-redux').connect const inherits = require('util').inherits @@ -16,13 +18,16 @@ const { conversionUtil, multiplyCurrencies } = require('../conversion-util') const { calcTokenAmount } = require('../token-util') const { getCurrentCurrency } = require('../selectors') +const { CONFIRM_TRANSACTION_ROUTE } = require('../routes') TxListItem.contextTypes = { t: PropTypes.func, } -module.exports = connect(mapStateToProps, mapDispatchToProps)(TxListItem) - +module.exports = compose( + withRouter, + connect(mapStateToProps, mapDispatchToProps) +)(TxListItem) function mapStateToProps (state) { return { @@ -216,6 +221,7 @@ TxListItem.prototype.setSelectedToken = function (tokenAddress) { TxListItem.prototype.resubmit = function () { const { transactionId } = this.props this.props.retryTransaction(transactionId) + .then(id => this.props.history.push(`${CONFIRM_TRANSACTION_ROUTE}/${id}`)) } TxListItem.prototype.render = function () { diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index fb38aaa76..461587cb1 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -7,6 +7,7 @@ const { compose } = require('recompose') const actions = require('./actions') const txHelper = require('../lib/tx-helper') const log = require('loglevel') +const R = require('ramda') const PendingTx = require('./components/pending-tx') const SignatureRequest = require('./components/signature-request') @@ -87,37 +88,74 @@ ConfirmTxScreen.prototype.componentDidUpdate = function (prevProps) { network, selectedAddressTxList, send, + history, + match: { params: { id: transactionId } = {} }, } = this.props - const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevProps - const prevUnconfTxList = txHelper(prevUnapprovedTxs, {}, {}, {}, network) - const prevTxData = prevUnconfTxList[prevIndex] || {} - const prevTx = selectedAddressTxList.find(({ id }) => id === prevTxData.id) || {} + + let prevTx + + if (transactionId) { + prevTx = R.find(({ id }) => id + '' === transactionId)(selectedAddressTxList) + } else { + const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevProps + const prevUnconfTxList = txHelper(prevUnapprovedTxs, {}, {}, {}, network) + const prevTxData = prevUnconfTxList[prevIndex] || {} + prevTx = selectedAddressTxList.find(({ id }) => id === prevTxData.id) || {} + } + const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network) - if (unconfTxList.length === 0 && - (prevTx.status === 'dropped' || !send.to && this.getUnapprovedMessagesTotal() === 0)) { + if (prevTx.status === 'dropped') { + this.props.dispatch(actions.showModal({ + name: 'TRANSACTION_CONFIRMED', + onHide: () => history.push(DEFAULT_ROUTE), + })) + + return + } + + if (unconfTxList.length === 0 && !send.to && this.getUnapprovedMessagesTotal() === 0) { this.props.history.push(DEFAULT_ROUTE) } } -ConfirmTxScreen.prototype.render = function () { - const props = this.props +ConfirmTxScreen.prototype.getTxData = function () { const { network, + index, + unapprovedTxs, + unapprovedMsgs, + unapprovedPersonalMsgs, + unapprovedTypedMessages, + match: { params: { id: transactionId } = {} }, + } = this.props + + const unconfTxList = txHelper( unapprovedTxs, - currentCurrency, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, + network + ) + + log.info(`rendering a combined ${unconfTxList.length} unconf msgs & txs`) + + return transactionId + ? R.find(({ id }) => id + '' === transactionId)(unconfTxList) + : unconfTxList[index] +} + +ConfirmTxScreen.prototype.render = function () { + const props = this.props + const { + currentCurrency, conversionRate, blockGasLimit, // provider, // computedBalances, } = props - var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network) - - var txData = unconfTxList[props.index] || {} + var txData = this.getTxData() || {} var txParams = txData.params || {} // var isNotification = isPopupOrNotification() === 'notification' @@ -136,7 +174,6 @@ ConfirmTxScreen.prototype.render = function () { ]), */ - log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`) return currentTxView({ // Properties diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 2b39eb8db..4e9d0848c 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -42,6 +42,7 @@ function reduceApp (state, action) { open: false, modalState: { name: null, + props: {}, }, previousModalState: { name: null, @@ -88,13 +89,17 @@ function reduceApp (state, action) { // modal methods: case actions.MODAL_OPEN: + const { name, ...modalProps } = action.payload + return extend(appState, { - modal: Object.assign( - state.appState.modal, - { open: true }, - { modalState: action.payload }, - { previousModalState: appState.modal.modalState}, - ), + modal: { + open: true, + modalState: { + name: name, + props: { ...modalProps }, + }, + previousModalState: { ...appState.modal.modalState }, + }, }) case actions.MODAL_CLOSE: @@ -102,7 +107,7 @@ function reduceApp (state, action) { modal: Object.assign( state.appState.modal, { open: false }, - { modalState: { name: null } }, + { modalState: { name: null, props: {} } }, { previousModalState: appState.modal.modalState}, ), }) -- cgit From d40971e7f30f86629f661a53e4c7b51f34397d87 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 30 May 2018 09:23:31 -0700 Subject: Fix error handling on incorrect password (#4401) --- .../pages/unlock-page/unlock-page.component.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pages/unlock-page/unlock-page.component.js b/ui/app/components/pages/unlock-page/unlock-page.component.js index b6384b32d..8bc3897da 100644 --- a/ui/app/components/pages/unlock-page/unlock-page.component.js +++ b/ui/app/components/pages/unlock-page/unlock-page.component.js @@ -34,14 +34,7 @@ class UnlockPage extends Component { } } - tryUnlockMetamask (password) { - const { tryUnlockMetamask, history } = this.props - tryUnlockMetamask(password) - .catch(({ message }) => this.setState({ error: message })) - .then(() => history.push(DEFAULT_ROUTE)) - } - - handleSubmit (event) { + async handleSubmit (event) { event.preventDefault() event.stopPropagation() @@ -54,9 +47,14 @@ class UnlockPage extends Component { this.setState({ error: null }) - tryUnlockMetamask(password) - .catch(({ message }) => this.setState({ error: message })) - .then(() => history.push(DEFAULT_ROUTE)) + try { + await tryUnlockMetamask(password) + } catch ({ message }) { + this.setState({ error: message }) + return + } + + history.push(DEFAULT_ROUTE) } handleInputChange ({ target }) { -- cgit From 389346913bf076fde6190a61afc4e3e4cd210afc Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 30 May 2018 10:38:53 -0700 Subject: Prevent loading screen from overlaying the app bar (#4417) --- ui/app/app.js | 1 - ui/app/components/loading-screen/loading-screen.component.js | 6 +----- ui/app/components/pending-tx/index.js | 5 +---- ui/app/css/itcss/components/loading-overlay.scss | 4 ++-- 4 files changed, 4 insertions(+), 12 deletions(-) (limited to 'ui') diff --git a/ui/app/app.js b/ui/app/app.js index aa2b24422..0e8b907df 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -137,7 +137,6 @@ class App extends Component { (isLoading || isLoadingNetwork) && h(Loading, { loadingMessage: loadMessage, - fullScreen: true, }), // content diff --git a/ui/app/components/loading-screen/loading-screen.component.js b/ui/app/components/loading-screen/loading-screen.component.js index bce2a4aac..6b843cfee 100644 --- a/ui/app/components/loading-screen/loading-screen.component.js +++ b/ui/app/components/loading-screen/loading-screen.component.js @@ -1,7 +1,6 @@ const { Component } = require('react') const h = require('react-hyperscript') const PropTypes = require('prop-types') -const classnames = require('classnames') const Spinner = require('../spinner') class LoadingScreen extends Component { @@ -12,9 +11,7 @@ class LoadingScreen extends Component { render () { return ( - h('.loading-overlay', { - className: classnames({ 'loading-overlay--full-screen': this.props.fullScreen }), - }, [ + h('.loading-overlay', [ h('.loading-overlay__container', [ h(Spinner, { color: '#F7C06C', @@ -29,7 +26,6 @@ class LoadingScreen extends Component { LoadingScreen.propTypes = { loadingMessage: PropTypes.string, - fullScreen: PropTypes.bool, } module.exports = LoadingScreen diff --git a/ui/app/components/pending-tx/index.js b/ui/app/components/pending-tx/index.js index 893538bcf..3f8cd8823 100644 --- a/ui/app/components/pending-tx/index.js +++ b/ui/app/components/pending-tx/index.js @@ -130,7 +130,6 @@ PendingTx.prototype.render = function () { if (isFetching) { return h(Loading, { - fullScreen: true, loadingMessage: this.context.t('generatingTransaction'), }) } @@ -157,9 +156,7 @@ PendingTx.prototype.render = function () { sendTransaction, }) default: - return h(Loading, { - fullScreen: true, - }) + return h(Loading) } } diff --git a/ui/app/css/itcss/components/loading-overlay.scss b/ui/app/css/itcss/components/loading-overlay.scss index c18b7fa59..b07d6af17 100644 --- a/ui/app/css/itcss/components/loading-overlay.scss +++ b/ui/app/css/itcss/components/loading-overlay.scss @@ -11,8 +11,8 @@ background: rgba(255, 255, 255, .8); @media screen and (max-width: 575px) { - margin-top: 56px; - height: calc(100% - 56px); + margin-top: 66px; + height: calc(100% - 66px); } @media screen and (min-width: 576px) { -- cgit From d454b5de2b03111a05c4e8a8b0a91e612b8f0266 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 31 May 2018 13:20:15 -0230 Subject: Token name is not hidden in wallet if balance is exceptionally long. --- ui/app/components/token-cell.js | 4 ++-- ui/app/css/itcss/components/token-list.scss | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js index c84117d84..4100d76a5 100644 --- a/ui/app/components/token-cell.js +++ b/ui/app/components/token-cell.js @@ -101,8 +101,8 @@ TokenCell.prototype.render = function () { h('div.token-list-item__balance-ellipsis', null, [ h('div.token-list-item__balance-wrapper', null, [ - h('h3.token-list-item__token-balance', `${string || 0} ${symbol}`), - + h('div.token-list-item__token-balance', `${string || 0}`), + h('div.token-list-item__token-symbol', symbol), showFiat && h('div.token-list-item__fiat-amount', { style: {}, }, formattedFiat), diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index e8de317e3..214bbc774 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -14,10 +14,16 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( min-width: 0; &__token-balance { - font-size: 1.5rem; + margin-right: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + flex: 1; + } + + &__token-balance, &__token-symbol { + font-size: 1.5rem; + display: inline-flex; @media #{$wallet-balance-breakpoint-range} { font-size: 95%; @@ -68,6 +74,8 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( &__balance-wrapper { flex: 1 1 auto; min-width: 0; + overflow: hidden; + text-overflow: ellipsis; } } -- cgit From f4d833cb09758beb62a65ad4011d16bdb81b33ff Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Tue, 29 May 2018 14:33:29 -0700 Subject: Change btn-secondary styles to btn-default. Make btn-secondary red warning style buttons --- ui/app/components/button/button.component.js | 23 +++++----- ui/app/components/button/button.stories.js | 19 ++++++++- ui/app/components/customize-gas-modal/index.js | 2 +- ui/app/components/modals/deposit-ether-modal.js | 2 +- .../components/modals/export-private-key-modal.js | 6 +-- .../pages/add-token/add-token.component.js | 2 +- .../confirm-add-token.component.js | 2 +- .../pages/create-account/import-account/json.js | 4 +- .../create-account/import-account/private-key.js | 6 +-- .../components/pages/create-account/new-account.js | 4 +- ui/app/components/pages/keychains/reveal-seed.js | 6 +-- ui/app/components/pages/settings/settings.js | 8 ++-- ui/app/components/shapeshift-form.js | 2 +- ui/app/components/signature-request.js | 4 +- ui/app/css/itcss/components/buttons.scss | 49 +++++++++++----------- ui/app/send-v2.js | 2 +- 16 files changed, 79 insertions(+), 62 deletions(-) (limited to 'ui') diff --git a/ui/app/components/button/button.component.js b/ui/app/components/button/button.component.js index fe3bf363c..e8e798445 100644 --- a/ui/app/components/button/button.component.js +++ b/ui/app/components/button/button.component.js @@ -2,20 +2,15 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -const SECONDARY = 'secondary' +const CLASSNAME_DEFAULT = 'btn-default' const CLASSNAME_PRIMARY = 'btn-primary' -const CLASSNAME_PRIMARY_LARGE = 'btn-primary--lg' const CLASSNAME_SECONDARY = 'btn-secondary' -const CLASSNAME_SECONDARY_LARGE = 'btn-secondary--lg' +const CLASSNAME_LARGE = 'btn--large' -const getClassName = (type, large = false) => { - let output = type === SECONDARY ? CLASSNAME_SECONDARY : CLASSNAME_PRIMARY - - if (large) { - output += ` ${type === SECONDARY ? CLASSNAME_SECONDARY_LARGE : CLASSNAME_PRIMARY_LARGE}` - } - - return output +const typeHash = { + default: CLASSNAME_DEFAULT, + primary: CLASSNAME_PRIMARY, + secondary: CLASSNAME_SECONDARY, } class Button extends Component { @@ -24,7 +19,11 @@ class Button extends Component { return ( ) - .add('secondary', () => ( + .add('secondary', () => + ) + .add('default', () => ( + )) .add('large primary', () => ( + )) diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js index 1ff8eea87..e3529041b 100644 --- a/ui/app/components/customize-gas-modal/index.js +++ b/ui/app/components/customize-gas-modal/index.js @@ -308,7 +308,7 @@ CustomizeGasModal.prototype.render = function () { }, [this.context.t('revert')]), h('div.send-v2__customize-gas__buttons', [ - h('button.btn-secondary.send-v2__customize-gas__cancel', { + h('button.btn-default.send-v2__customize-gas__cancel', { onClick: this.props.hideModal, style: { marginRight: '10px', diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js index ad5f9b695..2daa7fa1d 100644 --- a/ui/app/components/modals/deposit-ether-modal.js +++ b/ui/app/components/modals/deposit-ether-modal.js @@ -109,7 +109,7 @@ DepositEtherModal.prototype.renderRow = function ({ ]), !hideButton && h('div.deposit-ether-modal__buy-row__button', [ - h('button.btn-primary--lg.deposit-ether-modal__deposit-button', { + h('button.btn-primary.btn--large.deposit-ether-modal__deposit-button', { onClick: onButtonClick, }, [buttonLabel]), ]), diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js index 447e43b7a..80ece425f 100644 --- a/ui/app/components/modals/export-private-key-modal.js +++ b/ui/app/components/modals/export-private-key-modal.js @@ -87,14 +87,14 @@ 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-secondary--lg export-private-key__button export-private-key__button--cancel', + 'btn-default btn--large export-private-key__button export-private-key__button--cancel', () => hideModal(), 'Cancel' ), (privateKey - ? this.renderButton('btn-primary--lg export-private-key__button', () => hideModal(), this.context.t('done')) - : this.renderButton('btn-primary--lg export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), this.context.t('confirm')) + ? this.renderButton('btn-primary btn--large export-private-key__button', () => hideModal(), this.context.t('done')) + : this.renderButton('btn-primary btn--large export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), this.context.t('confirm')) ), ]) diff --git a/ui/app/components/pages/add-token/add-token.component.js b/ui/app/components/pages/add-token/add-token.component.js index 0677b4317..1f4b37b53 100644 --- a/ui/app/components/pages/add-token/add-token.component.js +++ b/ui/app/components/pages/add-token/add-token.component.js @@ -323,7 +323,7 @@ class AddToken extends Component {
+ +
+ + ) + } +} + +export default ConfirmResetAccount diff --git a/ui/app/components/modals/confirm-reset-account/confirm-reset-account.container.js b/ui/app/components/modals/confirm-reset-account/confirm-reset-account.container.js new file mode 100644 index 000000000..9630a5593 --- /dev/null +++ b/ui/app/components/modals/confirm-reset-account/confirm-reset-account.container.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux' +import ConfirmResetAccount from './confirm-reset-account.component' + +const { hideModal, resetAccount } = require('../../../actions') + +const mapDispatchToProps = dispatch => { + return { + hideModal: () => dispatch(hideModal()), + resetAccount: () => dispatch(resetAccount()), + } +} + +export default connect(null, mapDispatchToProps)(ConfirmResetAccount) diff --git a/ui/app/components/modals/confirm-reset-account/index.js b/ui/app/components/modals/confirm-reset-account/index.js new file mode 100644 index 000000000..c812ffc55 --- /dev/null +++ b/ui/app/components/modals/confirm-reset-account/index.js @@ -0,0 +1,2 @@ +import ConfirmResetAccount from './confirm-reset-account.container' +module.exports = ConfirmResetAccount diff --git a/ui/app/components/modals/index.scss b/ui/app/components/modals/index.scss index ec6207f7e..ad6fe16d3 100644 --- a/ui/app/components/modals/index.scss +++ b/ui/app/components/modals/index.scss @@ -1 +1,52 @@ -@import './transaction-confirmed/index'; +.modal-container { + width: 100%; + height: 100%; + background-color: #fff; + display: flex; + flex-flow: column; + border-radius: 8px; + + &__title { + font-size: 1.5rem; + font-weight: 500; + padding: 16px 0; + text-align: center; + } + + &__description { + text-align: center; + font-size: .875rem; + } + + &__content { + overflow-y: auto; + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + padding: 32px; + + @media screen and (max-width: 575px) { + justify-content: center; + padding: 28px 20px; + } + } + + &__footer { + display: flex; + flex-flow: row; + justify-content: center; + border-top: 1px solid #d2d8dd; + padding: 16px; + flex: 0 0 auto; + + &-button { + min-width: 0; + margin-right: 16px; + + &:last-of-type { + margin-right: 0; + } + } + } +} diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 841189277..85e85597a 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -19,8 +19,30 @@ const ShapeshiftDepositTxModal = require('./shapeshift-deposit-tx-modal.js') const HideTokenConfirmationModal = require('./hide-token-confirmation-modal') const CustomizeGasModal = require('../customize-gas-modal') const NotifcationModal = require('./notification-modal') -const ConfirmResetAccount = require('./notification-modals/confirm-reset-account') +const ConfirmResetAccount = require('./confirm-reset-account') const TransactionConfirmed = require('./transaction-confirmed') +const WelcomeBeta = require('./welcome-beta') +const Notification = require('./notification') + +const modalContainerBaseStyle = { + transform: 'translate3d(-50%, 0, 0px)', + border: '1px solid #CCCFD1', + borderRadius: '8px', + backgroundColor: '#FFFFFF', + boxShadow: '0 2px 22px 0 rgba(0,0,0,0.2)', +} + +const modalContainerLaptopStyle = { + ...modalContainerBaseStyle, + width: '344px', + top: '15%', +} + +const modalContainerMobileStyle = { + ...modalContainerBaseStyle, + width: '309px', + top: '12.5%', +} const accountModalStyle = { mobileModalStyle: { @@ -174,18 +196,18 @@ const MODALS = { BETA_UI_NOTIFICATION_MODAL: { contents: [ - h(NotifcationModal, { - header: 'uiWelcome', - message: 'uiWelcomeMessage', - }), + h(Notification, [ + h(WelcomeBeta), + ]), ], mobileModalStyle: { - width: '95%', - top: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh', + ...modalContainerMobileStyle, }, laptopModalStyle: { - width: '449px', - top: 'calc(33% + 45px)', + ...modalContainerLaptopStyle, + }, + contentStyle: { + borderRadius: '8px', }, }, @@ -209,12 +231,13 @@ const MODALS = { CONFIRM_RESET_ACCOUNT: { contents: h(ConfirmResetAccount), mobileModalStyle: { - width: '95%', - top: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh', + ...modalContainerMobileStyle, }, laptopModalStyle: { - width: '473px', - top: 'calc(33% + 45px)', + ...modalContainerLaptopStyle, + }, + contentStyle: { + borderRadius: '8px', }, }, @@ -269,31 +292,18 @@ const MODALS = { TRANSACTION_CONFIRMED: { disableBackdropClick: true, contents: [ - h(TransactionConfirmed, {}, []), + h(Notification, [ + h(TransactionConfirmed), + ]), ], 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', + ...modalContainerMobileStyle, }, laptopModalStyle: { - width: '344px', - transform: 'translate3d(-50%, 0, 0px)', - top: '15%', - border: '1px solid #CCCFD1', - borderRadius: '8px', - backgroundColor: '#FFFFFF', - boxShadow: '0 2px 22px 0 rgba(0,0,0,0.2)', + ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', - height: '100%', }, }, diff --git a/ui/app/components/modals/notification-modals/confirm-reset-account.js b/ui/app/components/modals/notification-modals/confirm-reset-account.js deleted file mode 100644 index 89fa9bef1..000000000 --- a/ui/app/components/modals/notification-modals/confirm-reset-account.js +++ /dev/null @@ -1,46 +0,0 @@ -const { Component } = require('react') -const PropTypes = require('prop-types') -const h = require('react-hyperscript') -const connect = require('react-redux').connect -const actions = require('../../../actions') -const NotifcationModal = require('../notification-modal') - -class ConfirmResetAccount extends Component { - render () { - const { resetAccount } = this.props - - return h(NotifcationModal, { - header: 'Are you sure you want to reset account?', - message: h('div', [ - - h('span', `Resetting is for developer use only. This button wipes the current account's transaction history, - which is used to calculate the current account nonce. `), - - h('a.notification-modal__link', { - href: 'http://metamask.helpscoutdocs.com/article/36-resetting-an-account', - target: '_blank', - onClick (event) { global.platform.openWindow({ url: event.target.href }) }, - }, 'Read more.'), - - ]), - showCancelButton: true, - showConfirmButton: true, - onConfirm: resetAccount, - - }) - } -} - -ConfirmResetAccount.propTypes = { - resetAccount: PropTypes.func, -} - -const mapDispatchToProps = dispatch => { - return { - resetAccount: () => { - dispatch(actions.resetAccount()) - }, - } -} - -module.exports = connect(null, mapDispatchToProps)(ConfirmResetAccount) diff --git a/ui/app/components/modals/notification/index.js b/ui/app/components/modals/notification/index.js new file mode 100644 index 000000000..d60a3129b --- /dev/null +++ b/ui/app/components/modals/notification/index.js @@ -0,0 +1,2 @@ +import Notification from './notification.container' +module.exports = Notification diff --git a/ui/app/components/modals/notification/notification.component.js b/ui/app/components/modals/notification/notification.component.js new file mode 100644 index 000000000..1af2f3ca8 --- /dev/null +++ b/ui/app/components/modals/notification/notification.component.js @@ -0,0 +1,30 @@ +import React from 'react' +import PropTypes from 'prop-types' +import Button from '../../button' + +const Notification = (props, context) => { + return ( +
+ { props.children } +
+ +
+
+ ) +} + +Notification.propTypes = { + onHide: PropTypes.func.isRequired, + children: PropTypes.element, +} + +Notification.contextTypes = { + t: PropTypes.func, +} + +export default Notification diff --git a/ui/app/components/modals/notification/notification.container.js b/ui/app/components/modals/notification/notification.container.js new file mode 100644 index 000000000..5b98714da --- /dev/null +++ b/ui/app/components/modals/notification/notification.container.js @@ -0,0 +1,38 @@ +import { connect } from 'react-redux' +import Notification from './notification.component' + +const { hideModal } = require('../../../actions') + +const mapStateToProps = state => { + const { appState: { modal: { modalState: { props } } } } = state + const { onHide } = props + return { + onHide, + } +} + +const mapDispatchToProps = dispatch => { + return { + hideModal: () => dispatch(hideModal()), + } +} + +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { onHide, ...otherStateProps } = stateProps + const { hideModal, ...otherDispatchProps } = dispatchProps + + return { + ...otherStateProps, + ...otherDispatchProps, + ...ownProps, + onHide: () => { + hideModal() + + if (onHide && typeof onHide === 'function') { + onHide() + } + }, + } +} + +export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notification) diff --git a/ui/app/components/modals/transaction-confirmed/index.js b/ui/app/components/modals/transaction-confirmed/index.js index c8db91388..cee8da7f8 100644 --- a/ui/app/components/modals/transaction-confirmed/index.js +++ b/ui/app/components/modals/transaction-confirmed/index.js @@ -1,2 +1,2 @@ -import TransactionConfirmed from './transaction-confirmed.container' +import TransactionConfirmed from './transaction-confirmed.component' module.exports = TransactionConfirmed diff --git a/ui/app/components/modals/transaction-confirmed/index.scss b/ui/app/components/modals/transaction-confirmed/index.scss deleted file mode 100644 index f8cd1f212..000000000 --- a/ui/app/components/modals/transaction-confirmed/index.scss +++ /dev/null @@ -1,21 +0,0 @@ -.transaction-confirmed { - display: flex; - flex-direction: column; - align-items: center; - padding: 32px; - - &__title { - font-size: 2rem; - padding: 16px 0; - } - - &__description { - text-align: center; - font-size: .875rem; - line-height: 1.5rem; - } - - @media screen and (max-width: 575px) { - justify-content: center; - } -} diff --git a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js index 8d3b288ae..c1c8a2976 100644 --- a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js +++ b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js @@ -1,42 +1,20 @@ -import React, { Component } from 'react' +import React from 'react' import PropTypes from 'prop-types' -import Button from '../../button' -class TransactionConfirmed extends Component { - render () { - const { t } = this.context +const TransactionConfirmed = (props, context) => { + const { t } = context - return ( -
-
- -
- { `${t('confirmed')}!` } -
-
- { t('initialTransactionConfirmed') } -
-
-
- -
+ return ( +
+ +
+ { `${t('confirmed')}!` }
- ) - } -} - -TransactionConfirmed.propTypes = { - hideModal: PropTypes.func.isRequired, - onHide: PropTypes.func.isRequired, +
+ { t('initialTransactionConfirmed') } +
+
+ ) } TransactionConfirmed.contextTypes = { diff --git a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js deleted file mode 100644 index 63872f7f2..000000000 --- a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js +++ /dev/null @@ -1,20 +0,0 @@ -import { connect } from 'react-redux' -import TransactionConfirmed from './transaction-confirmed.component' - -const { hideModal } = require('../../../actions') - -const mapStateToProps = state => { - const { appState: { modal: { modalState: { props } } } } = state - const { onHide } = props - return { - onHide, - } -} - -const mapDispatchToProps = dispatch => { - return { - hideModal: () => dispatch(hideModal()), - } -} - -export default connect(mapStateToProps, mapDispatchToProps)(TransactionConfirmed) diff --git a/ui/app/components/modals/welcome-beta/index.js b/ui/app/components/modals/welcome-beta/index.js new file mode 100644 index 000000000..515c9cdaf --- /dev/null +++ b/ui/app/components/modals/welcome-beta/index.js @@ -0,0 +1,2 @@ +import WelcomeBeta from './welcome-beta.component' +module.exports = WelcomeBeta diff --git a/ui/app/components/modals/welcome-beta/welcome-beta.component.js b/ui/app/components/modals/welcome-beta/welcome-beta.component.js new file mode 100644 index 000000000..61571723a --- /dev/null +++ b/ui/app/components/modals/welcome-beta/welcome-beta.component.js @@ -0,0 +1,23 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const TransactionConfirmed = (props, context) => { + const { t } = context + + return ( +
+
+ { `${t('uiWelcome')}` } +
+
+ { t('uiWelcomeMessage') } +
+
+ ) +} + +TransactionConfirmed.contextTypes = { + t: PropTypes.func, +} + +export default TransactionConfirmed -- cgit From fd98ed570e09faf12ac10e6340225fd586914558 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 31 May 2018 11:16:41 -0700 Subject: Fix ellipses --- ui/app/css/itcss/components/token-list.scss | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index 214bbc774..72fda372f 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -18,12 +18,13 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - flex: 1; + min-width: 0; + max-width: 100%; } &__token-balance, &__token-symbol { font-size: 1.5rem; - display: inline-flex; + flex: 0 0 auto; @media #{$wallet-balance-breakpoint-range} { font-size: 95%; @@ -72,10 +73,10 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( } &__balance-wrapper { - flex: 1 1 auto; + flex: 1; + flex-flow: row wrap; + display: flex; min-width: 0; - overflow: hidden; - text-overflow: ellipsis; } } -- cgit From 966583026a3eee2255ff1b05314f604874380ec5 Mon Sep 17 00:00:00 2001 From: Bobby Dresser Date: Thu, 31 May 2018 15:26:04 -0700 Subject: update helpscout links to zenhub --- .../token-list-placeholder/token-list-placeholder.component.js | 2 +- ui/app/components/pages/create-account/import-account/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js b/ui/app/components/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js index abd599b26..1611f817b 100644 --- a/ui/app/components/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js +++ b/ui/app/components/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js @@ -15,7 +15,7 @@ export default class TokenListPlaceholder extends Component {
diff --git a/ui/app/components/pages/create-account/import-account/index.js b/ui/app/components/pages/create-account/import-account/index.js index 52d3dcde9..e2e973af9 100644 --- a/ui/app/components/pages/create-account/import-account/index.js +++ b/ui/app/components/pages/create-account/import-account/index.js @@ -46,7 +46,7 @@ AccountImportSubview.prototype.render = function () { }, onClick: () => { global.platform.openWindow({ - url: 'https://metamask.helpscoutdocs.com/article/17-what-are-loose-accounts', + url: 'https://consensys.zendesk.com/hc/en-us/articles/360004180111-What-are-imported-accounts-New-UI', }) }, }, this.context.t('here')), -- cgit From 5a2771dd470161f5678e3245f90aeb3a1ce1b89c Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 4 Jun 2018 09:33:25 -0700 Subject: Indicate the current selected account on the popup account view (#4445) --- ui/app/components/index.scss | 2 + ui/app/components/selected-account/index.js | 2 + ui/app/components/selected-account/index.scss | 38 ++++++++++++++ .../selected-account/selected-account.component.js | 60 ++++++++++++++++++++++ .../selected-account/selected-account.container.js | 13 +++++ ui/app/components/tx-view.js | 28 +++------- ui/app/css/itcss/components/account-menu.scss | 4 ++ ui/app/css/itcss/components/hero-balance.scss | 1 + 8 files changed, 127 insertions(+), 21 deletions(-) create mode 100644 ui/app/components/selected-account/index.js create mode 100644 ui/app/components/selected-account/index.scss create mode 100644 ui/app/components/selected-account/selected-account.component.js create mode 100644 ui/app/components/selected-account/selected-account.container.js (limited to 'ui') diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index e69acff63..351640f6e 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -1,5 +1,7 @@ @import './export-text-container/index'; +@import './selected-account/index'; + @import './info-box/index'; @import './pages/index'; diff --git a/ui/app/components/selected-account/index.js b/ui/app/components/selected-account/index.js new file mode 100644 index 000000000..eb342181f --- /dev/null +++ b/ui/app/components/selected-account/index.js @@ -0,0 +1,2 @@ +import SelectedAccount from './selected-account.container' +module.exports = SelectedAccount diff --git a/ui/app/components/selected-account/index.scss b/ui/app/components/selected-account/index.scss new file mode 100644 index 000000000..5339a228b --- /dev/null +++ b/ui/app/components/selected-account/index.scss @@ -0,0 +1,38 @@ +.selected-account { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + flex: 1; + + &__name { + max-width: 200px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + text-align: center; + } + + &__address { + font-size: .75rem; + color: $silver-chalice; + } + + &__clickable { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 5px 15px; + border-radius: 10px; + cursor: pointer; + + &:hover { + background-color: #e8e6e8; + } + + &:active { + background-color: #d9d7da; + } + } +} diff --git a/ui/app/components/selected-account/selected-account.component.js b/ui/app/components/selected-account/selected-account.component.js new file mode 100644 index 000000000..3386a4196 --- /dev/null +++ b/ui/app/components/selected-account/selected-account.component.js @@ -0,0 +1,60 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import copyToClipboard from 'copy-to-clipboard' + +const Tooltip = require('../tooltip-v2.js') + +const addressStripper = (address = '') => { + if (address.length < 4) { + return address + } + + return `${address.slice(0, 4)}...${address.slice(-4)}` +} + +class SelectedAccount extends Component { + state = { + copied: false, + } + + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + selectedAddress: PropTypes.string, + selectedIdentity: PropTypes.object, + } + + render () { + const { t } = this.context + const { selectedAddress, selectedIdentity } = this.props + + return ( +
+ +
{ + this.setState({ copied: true }) + setTimeout(() => this.setState({ copied: false }), 3000) + copyToClipboard(selectedAddress) + }} + > +
+ { selectedIdentity.name } +
+
+ { addressStripper(selectedAddress) } +
+
+
+
+ ) + } +} + +export default SelectedAccount diff --git a/ui/app/components/selected-account/selected-account.container.js b/ui/app/components/selected-account/selected-account.container.js new file mode 100644 index 000000000..f9e061d15 --- /dev/null +++ b/ui/app/components/selected-account/selected-account.container.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux' +import SelectedAccount from './selected-account.component' + +const selectors = require('../../selectors') + +const mapStateToProps = state => { + return { + selectedAddress: selectors.getSelectedAddress(state), + selectedIdentity: selectors.getSelectedIdentity(state), + } +} + +export default connect(mapStateToProps)(SelectedAccount) diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js index 263f992c0..014497fcd 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -12,7 +12,7 @@ const { checksumAddress: toChecksumAddress } = require('../util') const BalanceComponent = require('./balance-component') const TxList = require('./tx-list') -const Identicon = require('./identicon') +const SelectedAccount = require('./selected-account') module.exports = compose( withRouter, @@ -103,7 +103,7 @@ TxView.prototype.renderButtons = function () { } TxView.prototype.render = function () { - const { selectedAddress, identity, network, isMascara } = this.props + const { isMascara } = this.props return h('div.tx-view.flex-column', { style: {}, @@ -111,10 +111,12 @@ TxView.prototype.render = function () { h('div.flex-row.phone-visible', { style: { - justifyContent: 'space-between', + justifyContent: 'center', alignItems: 'center', flex: '0 0 auto', - margin: '10px', + marginBottom: '16px', + padding: '5px', + borderBottom: '1px solid #e5e5e5', }, }, [ @@ -127,23 +129,7 @@ TxView.prototype.render = function () { onClick: () => this.props.sidebarOpen ? this.props.hideSidebar() : this.props.showSidebar(), }), - h('.identicon-wrapper.select-none', { - style: { - marginLeft: '0.9em', - }, - }, [ - h(Identicon, { - diameter: 24, - address: selectedAddress, - network, - }), - ]), - - h('span.account-name', { - style: {}, - }, [ - identity.name, - ]), + h(SelectedAccount), !isMascara && h('div.open-in-browser', { onClick: () => global.platform.openExtensionInBrowser(), diff --git a/ui/app/css/itcss/components/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss index 657760ab5..96fba890c 100644 --- a/ui/app/css/itcss/components/account-menu.scss +++ b/ui/app/css/itcss/components/account-menu.scss @@ -116,6 +116,10 @@ &__name { color: $white; font-size: 18px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + max-width: 200px; } &__balance { diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss index 69cde8a0f..09d66aedd 100644 --- a/ui/app/css/itcss/components/hero-balance.scss +++ b/ui/app/css/itcss/components/hero-balance.scss @@ -6,6 +6,7 @@ justify-content: flex-start; align-items: center; flex: 0 0 auto; + padding-top: 16px; } @media screen and (min-width: $break-large) { -- cgit From 3b6e96bac918925c4edc674e26dba8cc5feb1324 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 4 Jun 2018 20:43:32 -0230 Subject: Update hide-token-confirmation-modal.js to use new modalState schema (#4482) * Update hide-token-confirmation-modal.js to use new modalState schema (added in 41e38fe55). * Fix modalState props --- ui/app/components/modals/edit-account-name-modal.js | 2 +- ui/app/components/modals/hide-token-confirmation-modal.js | 2 +- ui/app/components/modals/shapeshift-deposit-tx-modal.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/modals/edit-account-name-modal.js b/ui/app/components/modals/edit-account-name-modal.js index 5681a3cad..edced8725 100644 --- a/ui/app/components/modals/edit-account-name-modal.js +++ b/ui/app/components/modals/edit-account-name-modal.js @@ -9,7 +9,7 @@ const { getSelectedAccount } = require('../../selectors') function mapStateToProps (state) { return { selectedAccount: getSelectedAccount(state), - identity: state.appState.modal.modalState.identity, + identity: state.appState.modal.modalState.props.identity, } } diff --git a/ui/app/components/modals/hide-token-confirmation-modal.js b/ui/app/components/modals/hide-token-confirmation-modal.js index 72e9c84eb..1518fa9a0 100644 --- a/ui/app/components/modals/hide-token-confirmation-modal.js +++ b/ui/app/components/modals/hide-token-confirmation-modal.js @@ -9,7 +9,7 @@ const Identicon = require('../identicon') function mapStateToProps (state) { return { network: state.metamask.network, - token: state.appState.modal.modalState.token, + token: state.appState.modal.modalState.props.token, } } diff --git a/ui/app/components/modals/shapeshift-deposit-tx-modal.js b/ui/app/components/modals/shapeshift-deposit-tx-modal.js index 24af5a0de..242c7b89d 100644 --- a/ui/app/components/modals/shapeshift-deposit-tx-modal.js +++ b/ui/app/components/modals/shapeshift-deposit-tx-modal.js @@ -8,7 +8,7 @@ const AccountModalContainer = require('./account-modal-container') function mapStateToProps (state) { return { - Qr: state.appState.modal.modalState.Qr, + Qr: state.appState.modal.modalState.props.Qr, } } -- cgit From 762695bfd943a8910e4f297a66d9b8cd44eb8579 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Tue, 5 Jun 2018 12:04:03 -0700 Subject: Ensure selectedAddress exists when render wallet --- ui/app/components/wallet-view.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ui') diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index 3b29dacac..538175cdf 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -111,6 +111,10 @@ WalletView.prototype.render = function () { const checksummedAddress = checksumAddress(selectedAddress) + if (!selectedAddress) { + throw new Error('selectedAddress should not be ' + String(selectedAddress)) + } + const keyring = keyrings.find((kr) => { return kr.accounts.includes(selectedAddress) || kr.accounts.includes(selectedIdentity.address) -- cgit From 665ac860e5d29c573e07161632b0043ba18ef1d4 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Tue, 5 Jun 2018 12:23:30 -0700 Subject: Remove selectedIdentity prop from wallet view The selectedIdentity property is computed based on the selectedAddress which means that using both the selectedAddress and the selectedIdentity is redundant. In the case of the Array#find call on the set of keyrings, we wouldn't have a situation where one is included and the other isn't. This changeset removes the selectedIdentity from the wallet view because it isn't needed. --- ui/app/components/wallet-view.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index 538175cdf..da142fad8 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -36,7 +36,6 @@ function mapStateToProps (state) { tokens: state.metamask.tokens, keyrings: state.metamask.keyrings, selectedAddress: selectors.getSelectedAddress(state), - selectedIdentity: selectors.getSelectedIdentity(state), selectedAccount: selectors.getSelectedAccount(state), selectedTokenAddress: state.metamask.selectedTokenAddress, } @@ -99,12 +98,12 @@ WalletView.prototype.render = function () { const { responsiveDisplayClassname, selectedAddress, - selectedIdentity, keyrings, showAccountDetailModal, sidebarOpen, hideSidebar, history, + identities, } = this.props // temporary logs + fake extra wallets // console.log('walletview, selectedAccount:', selectedAccount) @@ -116,8 +115,7 @@ WalletView.prototype.render = function () { } const keyring = keyrings.find((kr) => { - return kr.accounts.includes(selectedAddress) || - kr.accounts.includes(selectedIdentity.address) + return kr.accounts.includes(selectedAddress) }) const type = keyring.type @@ -149,7 +147,7 @@ WalletView.prototype.render = function () { h('span.account-name', { style: {}, }, [ - selectedIdentity.name, + identities[selectedAddress].name, ]), h('button.btn-clear.wallet-view__details-button.allcaps', this.context.t('details')), -- cgit