aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/app/actions.js50
-rw-r--r--ui/app/app.js3
-rw-r--r--ui/app/components/button/button.component.js23
-rw-r--r--ui/app/components/button/button.stories.js19
-rw-r--r--ui/app/components/customize-gas-modal/index.js2
-rw-r--r--ui/app/components/index.scss2
-rw-r--r--ui/app/components/loading-screen/loading-screen.component.js6
-rw-r--r--ui/app/components/modals/confirm-reset-account/confirm-reset-account.component.js54
-rw-r--r--ui/app/components/modals/confirm-reset-account/confirm-reset-account.container.js13
-rw-r--r--ui/app/components/modals/confirm-reset-account/index.js2
-rw-r--r--ui/app/components/modals/deposit-ether-modal.js2
-rw-r--r--ui/app/components/modals/export-private-key-modal.js6
-rw-r--r--ui/app/components/modals/index.scss52
-rw-r--r--ui/app/components/modals/modal.js71
-rw-r--r--ui/app/components/modals/notification-modals/confirm-reset-account.js46
-rw-r--r--ui/app/components/modals/notification/index.js2
-rw-r--r--ui/app/components/modals/notification/notification.component.js30
-rw-r--r--ui/app/components/modals/notification/notification.container.js38
-rw-r--r--ui/app/components/modals/transaction-confirmed/index.js2
-rw-r--r--ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js24
-rw-r--r--ui/app/components/modals/welcome-beta/index.js2
-rw-r--r--ui/app/components/modals/welcome-beta/welcome-beta.component.js23
-rw-r--r--ui/app/components/page-container/page-container-footer/page-container-footer.component.js2
-rw-r--r--ui/app/components/pages/add-token/add-token.component.js2
-rw-r--r--ui/app/components/pages/add-token/token-list/token-list-placeholder/index.scss4
-rw-r--r--ui/app/components/pages/confirm-add-token/confirm-add-token.component.js2
-rw-r--r--ui/app/components/pages/create-account/import-account/json.js4
-rw-r--r--ui/app/components/pages/create-account/import-account/private-key.js6
-rw-r--r--ui/app/components/pages/create-account/new-account.js4
-rw-r--r--ui/app/components/pages/keychains/reveal-seed.js6
-rw-r--r--ui/app/components/pages/settings/settings.js8
-rw-r--r--ui/app/components/pages/unlock-page/unlock-page.component.js20
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js60
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js57
-rw-r--r--ui/app/components/pending-tx/index.js5
-rw-r--r--ui/app/components/shapeshift-form.js2
-rw-r--r--ui/app/components/signature-request.js4
-rw-r--r--ui/app/components/text-field/text-field.component.js95
-rw-r--r--ui/app/components/text-field/text-field.stories.js29
-rw-r--r--ui/app/components/tx-list-item.js10
-rw-r--r--ui/app/conf-tx.js63
-rw-r--r--ui/app/css/itcss/components/buttons.scss49
-rw-r--r--ui/app/css/itcss/components/loading-overlay.scss4
-rw-r--r--ui/app/css/itcss/generic/index.scss6
-rw-r--r--ui/app/reducers/app.js19
45 files changed, 665 insertions, 268 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index fc2a838d4..ae6b9637d 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -512,17 +512,23 @@ function requestRevealSeedWords (password) {
}
function resetAccount () {
- return (dispatch) => {
- background.resetAccount((err, account) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.displayWarning(err.message))
- }
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
- log.info('Transaction history reset for ' + account)
- dispatch(actions.showAccountsPage())
- })
- }
+ return new Promise((resolve, reject) => {
+ background.resetAccount((err, account) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+
+ log.info('Transaction history reset for ' + account)
+ dispatch(actions.showAccountsPage())
+ resolve(account)
+ })
+ })
+ }
}
function addNewKeyring (type, opts) {
@@ -1449,16 +1455,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 c4fddf1eb..09f7fdef4 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: SendTransactionScreen }),
h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }),
h(Authenticated, { path: CONFIRM_ADD_TOKEN_ROUTE, exact, component: ConfirmAddTokenPage }),
@@ -137,7 +137,6 @@ class App extends Component {
(isLoading || isLoadingNetwork) && h(Loading, {
loadingMessage: loadMessage,
- fullScreen: true,
}),
// content
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 () {
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/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss
index 4cbed6093..f93daec04 100644
--- a/ui/app/css/itcss/components/buttons.scss
+++ b/ui/app/css/itcss/components/buttons.scss
@@ -2,10 +2,10 @@
Buttons
*/
+.btn-default,
.btn-primary,
-.btn-primary--lg,
-.btn-secondary,
-.btn-secondary--lg {
+.btn-secondary {
+ height: 44px;
background: $white;
display: flex;
justify-content: center;
@@ -20,10 +20,16 @@
width: 100%;
text-transform: uppercase;
outline: none;
+
+ &--disabled,
+ &[disabled] {
+ cursor: auto;
+ opacity: .5;
+ pointer-events: none;
+ }
}
-.btn-primary,
-.btn-primary--lg {
+.btn-primary {
color: $curious-blue;
border: 2px solid $spindle;
@@ -35,17 +41,23 @@
&:hover {
border-color: $curious-blue;
}
+}
- &--disabled,
- &[disabled] {
- cursor: auto;
- opacity: .5;
- pointer-events: none;
+.btn-secondary {
+ color: $monzo;
+ border: 2px solid lighten($monzo, 40%);
+
+ &:active {
+ background: lighten($monzo, 55%);
+ border-color: $monzo;
+ }
+
+ &:hover {
+ border-color: $monzo;
}
}
-.btn-secondary,
-.btn-secondary--lg {
+.btn-default {
color: $scorpion;
border: 2px solid $dusty-gray;
@@ -57,20 +69,9 @@
&:hover {
border-color: $scorpion;
}
-
- &--disabled,
- &[disabled] {
- cursor: auto;
- opacity: .5;
- pointer-events: none;
- }
-}
-
-.btn-primary, .btn-secondary {
- height: 44px;
}
-.btn-primary--lg, .btn-secondary--lg {
+.btn--large {
height: 54px;
}
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) {
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index f667eeda8..3525d2003 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -191,11 +191,13 @@ input.large-input {
}
&--full-width {
- width: initial;
+ width: 100% !important;
}
&--full-height {
- height: 100%;
+ height: 100% !important;
+ max-height: initial !important;
+ min-height: initial !important;
}
&__content {
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},
),
})