diff options
Merge branch 'develop' into i3725-refactor-send-component-
Diffstat (limited to 'ui/app/components')
38 files changed, 539 insertions, 200 deletions
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 ( <button - className={classnames(getClassName(type, large), className)} + className={classnames( + typeHash[type], + large && CLASSNAME_LARGE, + className + )} { ...buttonProps } > { this.props.children } diff --git a/ui/app/components/button/button.stories.js b/ui/app/components/button/button.stories.js index d1e14e869..dec084a25 100644 --- a/ui/app/components/button/button.stories.js +++ b/ui/app/components/button/button.stories.js @@ -13,13 +13,21 @@ storiesOf('Button', module) {text('text', 'Click me')} </Button> ) - .add('secondary', () => ( + .add('secondary', () => <Button onClick={action('clicked')} type="secondary" > {text('text', 'Click me')} </Button> + ) + .add('default', () => ( + <Button + onClick={action('clicked')} + type="default" + > + {text('text', 'Click me')} + </Button> )) .add('large primary', () => ( <Button @@ -39,3 +47,12 @@ storiesOf('Button', module) {text('text', 'Click me')} </Button> )) + .add('large default', () => ( + <Button + onClick={action('clicked')} + type="default" + large + > + {text('text', 'Click me')} + </Button> + )) diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js index df933e363..2dd0cbb0e 100644 --- a/ui/app/components/customize-gas-modal/index.js +++ b/ui/app/components/customize-gas-modal/index.js @@ -312,7 +312,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/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/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/modals/confirm-reset-account/confirm-reset-account.component.js b/ui/app/components/modals/confirm-reset-account/confirm-reset-account.component.js new file mode 100644 index 000000000..14a4da62a --- /dev/null +++ b/ui/app/components/modals/confirm-reset-account/confirm-reset-account.component.js @@ -0,0 +1,54 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Button from '../../button' + +class ConfirmResetAccount extends Component { + static propTypes = { + hideModal: PropTypes.func.isRequired, + resetAccount: PropTypes.func.isRequired, + } + + static contextTypes = { + t: PropTypes.func, + } + + handleReset () { + this.props.resetAccount() + .then(() => this.props.hideModal()) + } + + render () { + const { t } = this.context + + return ( + <div className="modal-container"> + <div className="modal-container__content"> + <div className="modal-container__title"> + { `${t('resetAccount')}?` } + </div> + <div className="modal-container__description"> + { t('resetAccountDescription') } + </div> + </div> + <div className="modal-container__footer"> + <Button + type="default" + className="modal-container__footer-button" + onClick={() => this.props.hideModal()} + > + { t('nevermind') } + </Button> + <Button + type="secondary" + className="modal-container__footer-button" + onClick={() => this.handleReset()} + > + { t('reset') } + </Button> + </div> + </div> + ) + } +} + +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/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/modals/index.scss b/ui/app/components/modals/index.scss new file mode 100644 index 000000000..ad6fe16d3 --- /dev/null +++ b/ui/app/components/modals/index.scss @@ -0,0 +1,52 @@ +.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 43dcd20ae..85e85597a 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -19,7 +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: { @@ -173,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', }, }, @@ -208,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', }, }, @@ -265,6 +289,24 @@ const MODALS = { }, }, + TRANSACTION_CONFIRMED: { + disableBackdropClick: true, + contents: [ + h(Notification, [ + h(TransactionConfirmed), + ]), + ], + mobileModalStyle: { + ...modalContainerMobileStyle, + }, + laptopModalStyle: { + ...modalContainerLaptopStyle, + }, + contentStyle: { + borderRadius: '8px', + }, + }, + DEFAULT: { contents: [], mobileModalStyle: {}, @@ -306,7 +348,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 +368,7 @@ Modal.prototype.render = function () { modalStyle, contentStyle, backdropStyle: BACKDROPSTYLE, + closeOnClick: !disableBackdropClick, }, children, ) 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 f1a605498..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 ( + <div className="modal-container"> + { props.children } + <div className="modal-container__footer"> + <Button + type="primary" + onClick={() => props.onHide()} + > + { context.t('ok') } + </Button> + </div> + </div> + ) +} + +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 new file mode 100644 index 000000000..cee8da7f8 --- /dev/null +++ b/ui/app/components/modals/transaction-confirmed/index.js @@ -0,0 +1,2 @@ +import TransactionConfirmed from './transaction-confirmed.component' +module.exports = TransactionConfirmed 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..c1c8a2976 --- /dev/null +++ b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js @@ -0,0 +1,24 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const TransactionConfirmed = (props, context) => { + const { t } = context + + return ( + <div className="modal-container__content"> + <img src="images/check-icon.svg" /> + <div className="modal-container__title"> + { `${t('confirmed')}!` } + </div> + <div className="modal-container__description"> + { t('initialTransactionConfirmed') } + </div> + </div> + ) +} + +TransactionConfirmed.contextTypes = { + t: PropTypes.func, +} + +export default 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 ( + <div className="modal-container__content"> + <div className="modal-container__title"> + { `${t('uiWelcome')}` } + </div> + <div className="modal-container__description"> + { t('uiWelcomeMessage') } + </div> + </div> + ) +} + +TransactionConfirmed.contextTypes = { + t: PropTypes.func, +} + +export default TransactionConfirmed diff --git a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js index 9172aea94..0458ae78a 100644 --- a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js +++ b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js @@ -29,7 +29,7 @@ export default class PageContainerFooter extends Component { <div className="page-container__footer"> <Button - type="secondary" + type="default" large={true} className="page-container__footer-button" onClick={() => onCancel()} 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 { </div> <div className="page-container__footer"> <Button - type="secondary" + type="default" large className="page-container__footer-button" onClick={() => { 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 { diff --git a/ui/app/components/pages/confirm-add-token/confirm-add-token.component.js b/ui/app/components/pages/confirm-add-token/confirm-add-token.component.js index 9db9efc37..65d654b92 100644 --- a/ui/app/components/pages/confirm-add-token/confirm-add-token.component.js +++ b/ui/app/components/pages/confirm-add-token/confirm-add-token.component.js @@ -87,7 +87,7 @@ export default class ConfirmAddToken extends Component { </div> <div className="page-container__footer"> <Button - type="secondary" + type="default" large className="page-container__footer-button" onClick={() => history.push(ADD_TOKEN_ROUTE)} diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 0a3314b2a..0164417ec 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -51,7 +51,7 @@ class JsonImportSubview extends Component { h('div.new-account-create-form__buttons', {}, [ - h('button.btn-secondary.new-account-create-form__button', { + h('button.btn-default.new-account-create-form__button', { onClick: () => this.props.history.push(DEFAULT_ROUTE), }, [ this.context.t('cancel'), @@ -105,7 +105,7 @@ class JsonImportSubview extends Component { } this.props.importNewJsonAccount([ fileContents, password ]) - // JS runtime requires caught rejections but failures are handled by Redux + // JS runtime requires caught rejections but failures are handled by Redux .catch() } } diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index df7ac910a..e55a47a3c 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -59,13 +59,13 @@ PrivateKeyImportView.prototype.render = function () { h('div.new-account-import-form__buttons', {}, [ - h('button.btn-secondary--lg.new-account-create-form__button', { + h('button.btn-default.btn--large.new-account-create-form__button', { onClick: () => this.props.history.push(DEFAULT_ROUTE), }, [ this.context.t('cancel'), ]), - h('button.btn-primary--lg.new-account-create-form__button', { + h('button.btn-primary.btn--large.new-account-create-form__button', { onClick: () => this.createNewKeychain(), }, [ this.context.t('import'), @@ -91,7 +91,7 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { const { importNewAccount, history } = this.props importNewAccount('Private Key', [ privateKey ]) - // JS runtime requires caught rejections but failures are handled by Redux + // JS runtime requires caught rejections but failures are handled by Redux .catch() .then(() => history.push(DEFAULT_ROUTE)) } diff --git a/ui/app/components/pages/create-account/new-account.js b/ui/app/components/pages/create-account/new-account.js index 03a5ee72d..9c94990e0 100644 --- a/ui/app/components/pages/create-account/new-account.js +++ b/ui/app/components/pages/create-account/new-account.js @@ -38,13 +38,13 @@ class NewAccountCreateForm extends Component { h('div.new-account-create-form__buttons', {}, [ - h('button.btn-secondary--lg.new-account-create-form__button', { + h('button.btn-default.btn--large.new-account-create-form__button', { onClick: () => history.push(DEFAULT_ROUTE), }, [ this.context.t('cancel'), ]), - h('button.btn-primary--lg.new-account-create-form__button', { + h('button.btn-primary.btn--large.new-account-create-form__button', { onClick: () => { createAccount(newAccountName || defaultAccountName) .then(() => history.push(DEFAULT_ROUTE)) diff --git a/ui/app/components/pages/keychains/reveal-seed.js b/ui/app/components/pages/keychains/reveal-seed.js index 685c81074..7d7d3f462 100644 --- a/ui/app/components/pages/keychains/reveal-seed.js +++ b/ui/app/components/pages/keychains/reveal-seed.js @@ -106,10 +106,10 @@ class RevealSeedPage extends Component { renderPasswordPromptFooter () { return ( h('.page-container__footer', [ - h('button.btn-secondary--lg.page-container__footer-button', { + h('button.btn-default.btn--large.page-container__footer-button', { onClick: () => this.props.history.push(DEFAULT_ROUTE), }, this.context.t('cancel')), - h('button.btn-primary--lg.page-container__footer-button', { + h('button.btn-primary.btn--large.page-container__footer-button', { onClick: event => this.handleSubmit(event), disabled: this.state.password === '', }, this.context.t('next')), @@ -120,7 +120,7 @@ class RevealSeedPage extends Component { renderRevealSeedFooter () { return ( h('.page-container__footer', [ - h('button.btn-secondary--lg.page-container__footer-button', { + h('button.btn-default.btn--large.page-container__footer-button', { onClick: () => this.props.history.push(DEFAULT_ROUTE), }, this.context.t('close')), ]) diff --git a/ui/app/components/pages/settings/settings.js b/ui/app/components/pages/settings/settings.js index f58ac7ddf..ff42a13de 100644 --- a/ui/app/components/pages/settings/settings.js +++ b/ui/app/components/pages/settings/settings.js @@ -217,7 +217,7 @@ class Settings extends Component { ]), h('div.settings__content-item', [ h('div.settings__content-item-col', [ - h('button.btn-primary--lg.settings__button', { + h('button.btn-primary.btn--large.settings__button', { onClick (event) { window.logStateString((err, result) => { if (err) { @@ -242,7 +242,7 @@ class Settings extends Component { h('div.settings__content-item', this.context.t('revealSeedWords')), h('div.settings__content-item', [ h('div.settings__content-item-col', [ - h('button.btn-primary--lg.settings__button--red', { + h('button.btn-primary.btn--large.settings__button--red', { onClick: event => { event.preventDefault() history.push(REVEAL_SEED_ROUTE) @@ -262,7 +262,7 @@ class Settings extends Component { h('div.settings__content-item', this.context.t('useOldUI')), h('div.settings__content-item', [ h('div.settings__content-item-col', [ - h('button.btn-primary--lg.settings__button--orange', { + h('button.btn-primary.btn--large.settings__button--orange', { onClick (event) { event.preventDefault() setFeatureFlagToBeta() @@ -281,7 +281,7 @@ class Settings extends Component { h('div.settings__content-item', this.context.t('resetAccount')), h('div.settings__content-item', [ h('div.settings__content-item-col', [ - h('button.btn-primary--lg.settings__button--orange', { + h('button.btn-primary.btn--large.settings__button--orange', { onClick (event) { event.preventDefault() showResetAccountConfirmationModal() 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..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) - .then(() => history.push(DEFAULT_ROUTE)) - .catch(({ message }) => this.setState({ error: message })) - } - - handleSubmit (event) { + async handleSubmit (event) { event.preventDefault() event.stopPropagation() @@ -54,9 +47,14 @@ class UnlockPage extends Component { this.setState({ error: null }) - tryUnlockMetamask(password) - .then(() => history.push(DEFAULT_ROUTE)) - .catch(({ message }) => this.setState({ error: message })) + try { + await tryUnlockMetamask(password) + } catch ({ message }) { + this.setState({ error: message }) + return + } + + history.push(DEFAULT_ROUTE) } handleInputChange ({ target }) { diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 92df00e9b..97d0318ea 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -295,18 +295,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 () { @@ -324,6 +354,7 @@ ConfirmSendEther.prototype.render = function () { }, } = this.props const txMeta = this.gatherTxMeta() + const isTxReprice = Boolean(txMeta.lastGasPrice) const txParams = txMeta.txParams || {} const { @@ -342,11 +373,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) @@ -366,19 +392,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 b21e1473e..1802d3143 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 { @@ -43,6 +44,11 @@ import { updateSendErrors, } from '../../ducks/send.duck' +const { + ENVIRONMENT_TYPE_POPUP, + ENVIRONMENT_TYPE_NOTIFICATION, +} = require('../../../../app/scripts/lib/enums') + ConfirmSendToken.contextTypes = { t: PropTypes.func, } @@ -434,6 +440,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 { @@ -447,25 +490,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/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/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js index 22ab64426..93d2023b5 100644 --- a/ui/app/components/shapeshift-form.js +++ b/ui/app/components/shapeshift-form.js @@ -242,7 +242,7 @@ ShapeshiftForm.prototype.render = function () { ]), - !depositAddress && h('button.btn-primary--lg.shapeshift-form__shapeshift-buy-btn', { + !depositAddress && h('button.btn-primary.btn--large.shapeshift-form__shapeshift-buy-btn', { className: btnClass, disabled: !token, onClick: () => this.onBuyWithShapeShift(), diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js index 474fcf439..ab780dcf4 100644 --- a/ui/app/components/signature-request.js +++ b/ui/app/components/signature-request.js @@ -235,12 +235,12 @@ SignatureRequest.prototype.renderFooter = function () { } return h('div.request-signature__footer', [ - h('button.btn-secondary--lg.request-signature__footer__cancel-button', { + h('button.btn-default.btn--large.request-signature__footer__cancel-button', { onClick: event => { cancel(event).then(() => this.props.history.push(DEFAULT_ROUTE)) }, }, this.context.t('cancel')), - h('button.btn-primary--lg', { + h('button.btn-primary.btn--large', { onClick: event => { sign(event).then(() => this.props.history.push(DEFAULT_ROUTE)) }, 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 ( + <MaterialTextField + error={Boolean(error)} + helperText={error} + InputLabelProps={{ + shrink: material ? undefined : true, + className: material ? '' : (largeLabel ? classes.largeInputLabel : classes.inputLabel), + FormLabelClasses: { + root: material ? classes.materialLabel : classes.formLabel, + focused: material ? classes.materialFocused : classes.formLabelFocused, + error: classes.materialError, + }, + }} + InputProps={{ + startAdornment: startAdornment || undefined, + disableUnderline: !material, + classes: { + root: material ? '' : classes.inputRoot, + input: material ? '' : classes.input, + underline: material ? classes.materialUnderline : '', + focused: material ? '' : classes.inputFocused, + }, + }} + {...textFieldProps} + /> + ) +} - render () { - const { error, classes, material, startAdornment, ...textFieldProps } = this.props +TextField.defaultProps = { + error: null, +} - return ( - <MaterialTextField - error={Boolean(error)} - helperText={error} - InputLabelProps={{ - shrink: material ? undefined : true, - className: material ? '' : classes.inputLabel, - FormLabelClasses: { - root: material ? classes.materialLabel : classes.formLabel, - focused: material ? classes.materialFocused : classes.formLabelFocused, - error: classes.materialError, - }, - }} - InputProps={{ - startAdornment: startAdornment || undefined, - disableUnderline: !material, - classes: { - root: material ? '' : classes.inputRoot, - input: material ? '' : classes.input, - underline: material ? classes.materialUnderline : '', - focused: material ? '' : classes.inputFocused, - }, - }} - {...textFieldProps} - /> - ) - } +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', () => + <TextField + label="Text" + type="text" + largeLabel + /> + ) + .add('Material text', () => + <TextField + label="Text" + type="text" + material + /> + ) + .add('Material password', () => + <TextField + label="Password" + type="password" + material + /> + ) + .add('Material error', () => + <TextField + type="text" + label="Name" + error="Invalid value" + material + /> + ) diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js index 1eed06c3b..9a2fb5311 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 () { |