aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js32
-rw-r--r--ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.js1
-rw-r--r--ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.scss17
-rw-r--r--ui/app/components/modals/cancel-transaction/cancel-transaction.component.js71
-rw-r--r--ui/app/components/modals/cancel-transaction/cancel-transaction.container.js55
-rw-r--r--ui/app/components/modals/cancel-transaction/index.js1
-rw-r--r--ui/app/components/modals/cancel-transaction/index.scss18
-rw-r--r--ui/app/components/modals/confirm-remove-account/confirm-remove-account.component.js67
-rw-r--r--ui/app/components/modals/confirm-remove-account/confirm-remove-account.container.js8
-rw-r--r--ui/app/components/modals/confirm-remove-account/index.js3
-rw-r--r--ui/app/components/modals/confirm-remove-account/index.scss58
-rw-r--r--ui/app/components/modals/confirm-reset-account/confirm-reset-account.component.js48
-rw-r--r--ui/app/components/modals/confirm-reset-account/confirm-reset-account.container.js11
-rw-r--r--ui/app/components/modals/confirm-reset-account/index.js3
-rw-r--r--ui/app/components/modals/index.scss109
-rw-r--r--ui/app/components/modals/modal.js40
-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.js3
-rw-r--r--ui/app/components/modals/transaction-confirmed/index.scss22
-rw-r--r--ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js59
-rw-r--r--ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js4
-rw-r--r--ui/app/components/modals/welcome-beta/index.js3
-rw-r--r--ui/app/components/modals/welcome-beta/welcome-beta.component.js23
-rw-r--r--ui/app/components/modals/welcome-beta/welcome-beta.container.js4
-rw-r--r--ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js5
-rw-r--r--ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js4
-rw-r--r--ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js22
-rw-r--r--ui/app/components/transaction-list-item/transaction-list-item.component.js28
-rw-r--r--ui/app/components/transaction-list-item/transaction-list-item.container.js5
-rw-r--r--ui/app/components/transaction-list/transaction-list.component.js5
-rw-r--r--ui/app/conf-tx.js2
-rw-r--r--ui/app/constants/transactions.js1
-rw-r--r--ui/app/helpers/conversions.util.js12
-rw-r--r--ui/app/helpers/transactions.util.js7
36 files changed, 500 insertions, 321 deletions
diff --git a/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js b/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js
new file mode 100644
index 000000000..56765698e
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js
@@ -0,0 +1,32 @@
+import React, { PureComponent } from 'react'
+import PropTypes from 'prop-types'
+import classnames from 'classnames'
+import CurrencyDisplay from '../../../currency-display'
+import { ETH } from '../../../../constants/common'
+
+export default class CancelTransaction extends PureComponent {
+ static propTypes = {
+ className: PropTypes.string,
+ value: PropTypes.string,
+ }
+
+ render () {
+ const { className, value } = this.props
+ console.log('VALUE', value)
+
+ return (
+ <div className={classnames('cancel-transaction-gas-fee', className)}>
+ <CurrencyDisplay
+ className="cancel-transaction-gas-fee__eth"
+ currency={ETH}
+ value={value}
+ numberOfDecimals={6}
+ />
+ <CurrencyDisplay
+ className="cancel-transaction-gas-fee__fiat"
+ value={value}
+ />
+ </div>
+ )
+ }
+}
diff --git a/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.js b/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.js
new file mode 100644
index 000000000..1a9ae2e07
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.js
@@ -0,0 +1 @@
+export { default } from './cancel-transaction-gas-fee.component'
diff --git a/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.scss b/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.scss
new file mode 100644
index 000000000..ce81dd448
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/cancel-transaction-gas-fee/index.scss
@@ -0,0 +1,17 @@
+.cancel-transaction-gas-fee {
+ background: #F1F4F9;
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 12px;
+
+ &__eth {
+ font-size: 1.5rem;
+ font-weight: 500;
+ }
+
+ &__fiat {
+ font-size: .75rem;
+ }
+}
diff --git a/ui/app/components/modals/cancel-transaction/cancel-transaction.component.js b/ui/app/components/modals/cancel-transaction/cancel-transaction.component.js
new file mode 100644
index 000000000..f5f0ea783
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/cancel-transaction.component.js
@@ -0,0 +1,71 @@
+import React, { PureComponent } from 'react'
+import PropTypes from 'prop-types'
+import Modal from '../../modal'
+import CancelTransactionGasFee from './cancel-transaction-gas-fee'
+import { SUBMITTED_STATUS } from '../../../constants/transactions'
+import { decimalToHex } from '../../../helpers/conversions.util'
+import { getHexGasTotal } from '../../../helpers/confirm-transaction/util'
+
+export default class CancelTransaction extends PureComponent {
+ static contextTypes = {
+ t: PropTypes.func,
+ }
+
+ static propTypes = {
+ createCancelTransaction: PropTypes.func,
+ hideModal: PropTypes.func,
+ showTransactionConfirmedModal: PropTypes.func,
+ transactionStatus: PropTypes.string,
+ defaultNewGasPrice: PropTypes.string,
+ }
+
+ componentDidUpdate () {
+ const { transactionStatus, showTransactionConfirmedModal } = this.props
+
+ if (transactionStatus !== SUBMITTED_STATUS) {
+ showTransactionConfirmedModal()
+ return
+ }
+ }
+
+ handleSubmit = async () => {
+ const { createCancelTransaction, hideModal } = this.props
+
+ await createCancelTransaction()
+ hideModal()
+ }
+
+ handleCancel = () => {
+ this.props.hideModal()
+ }
+
+ render () {
+ const { t } = this.context
+ const { defaultNewGasPrice: gasPrice } = this.props
+ const newGasFee = getHexGasTotal({ gasPrice, gasLimit: decimalToHex(21000) })
+
+ return (
+ <Modal
+ headerText={t('attemptToCancel')}
+ onSubmit={this.handleSubmit}
+ onCancel={this.handleCancel}
+ submitText={t('yesLetsTry')}
+ cancelText={t('nevermind')}
+ submitType="secondary"
+ >
+ <div>
+ <div className="cancel-transaction__title">
+ { t('cancellationGasFee') }
+ </div>
+ <CancelTransactionGasFee
+ className="cancel-transaction__cancel-transaction-gas-fee-container"
+ value={newGasFee}
+ />
+ <div className="cancel-transaction__description">
+ { t('attemptToCancelDescription') }
+ </div>
+ </div>
+ </Modal>
+ )
+ }
+}
diff --git a/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js b/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js
new file mode 100644
index 000000000..15bff4bc6
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js
@@ -0,0 +1,55 @@
+import { connect } from 'react-redux'
+import { compose } from 'recompose'
+import R from 'ramda'
+import { multiplyCurrencies } from '../../../conversion-util'
+import { bnToHex } from '../../../helpers/conversions.util'
+import withModalProps from '../../../higher-order-components/with-modal-props'
+import CancelTransaction from './cancel-transaction.component'
+import { showModal, hideModal, createCancelTransaction } from '../../../actions'
+
+const mapStateToProps = (state, ownProps) => {
+ const { metamask } = state
+ const { transactionId, originalGasPrice } = ownProps
+ const { selectedAddressTxList } = metamask
+ const transaction = R.find(({ id }) => id === transactionId)(selectedAddressTxList)
+ const transactionStatus = transaction ? transaction.status : ''
+
+ const defaultNewGasPrice = bnToHex(multiplyCurrencies(originalGasPrice, 1.1))
+
+ return {
+ transactionId,
+ transactionStatus,
+ originalGasPrice,
+ defaultNewGasPrice,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ hideModal: () => dispatch(hideModal()),
+ createCancelTransaction: txId => dispatch(createCancelTransaction(txId)),
+ showTransactionConfirmedModal: () => dispatch(showModal({ name: 'TRANSACTION_CONFIRMED' })),
+ }
+}
+
+const mergeProps = (stateProps, dispatchProps, ownProps) => {
+ const { transactionId, ...restStateProps } = stateProps
+ const {
+ createCancelTransaction: dispatchCreateCancelTransaction,
+ ...restDispatchProps
+ } = dispatchProps
+
+ return {
+ ...restStateProps,
+ ...restDispatchProps,
+ ...ownProps,
+ createCancelTransaction: newGasPrice => {
+ return dispatchCreateCancelTransaction(transactionId, newGasPrice)
+ },
+ }
+}
+
+export default compose(
+ withModalProps,
+ connect(mapStateToProps, mapDispatchToProps, mergeProps),
+)(CancelTransaction)
diff --git a/ui/app/components/modals/cancel-transaction/index.js b/ui/app/components/modals/cancel-transaction/index.js
new file mode 100644
index 000000000..7abc871ee
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/index.js
@@ -0,0 +1 @@
+export { default } from './cancel-transaction.container'
diff --git a/ui/app/components/modals/cancel-transaction/index.scss b/ui/app/components/modals/cancel-transaction/index.scss
new file mode 100644
index 000000000..62e8e36fd
--- /dev/null
+++ b/ui/app/components/modals/cancel-transaction/index.scss
@@ -0,0 +1,18 @@
+@import './cancel-transaction-gas-fee/index';
+
+.cancel-transaction {
+ &__title {
+ font-weight: 500;
+ padding-bottom: 16px;
+ text-align: center;
+ }
+
+ &__description {
+ text-align: center;
+ font-size: .875rem;
+ }
+
+ &__cancel-transaction-gas-fee-container {
+ margin-bottom: 16px;
+ }
+} \ No newline at end of file
diff --git a/ui/app/components/modals/confirm-remove-account/confirm-remove-account.component.js b/ui/app/components/modals/confirm-remove-account/confirm-remove-account.component.js
index 5a9f0f289..483c7062f 100644
--- a/ui/app/components/modals/confirm-remove-account/confirm-remove-account.component.js
+++ b/ui/app/components/modals/confirm-remove-account/confirm-remove-account.component.js
@@ -1,6 +1,6 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import Button from '../../button'
+import Modal from '../../modal'
import { addressSummary } from '../../../util'
import Identicon from '../../identicon'
import genAccountLink from '../../../../lib/account-link'
@@ -25,22 +25,22 @@ class ConfirmRemoveAccount extends Component {
renderSelectedAccount () {
const { identity } = this.props
return (
- <div className="modal-container__account">
- <div className="modal-container__account__identicon">
+ <div className="confirm-remove-account__account">
+ <div className="confirm-remove-account__account__identicon">
<Identicon
- address={identity.address}
- diameter={32}
+ address={identity.address}
+ diameter={32}
/>
</div>
- <div className="modal-container__account__name">
- <span className="modal-container__account__label">Name</span>
- <span className="account_value">{identity.name}</span>
+ <div className="confirm-remove-account__account__name">
+ <span className="confirm-remove-account__account__label">Name</span>
+ <span className="account_value">{identity.name}</span>
</div>
- <div className="modal-container__account__address">
- <span className="modal-container__account__label">Public Address</span>
- <span className="account_value">{ addressSummary(identity.address, 4, 4) }</span>
+ <div className="confirm-remove-account__account__address">
+ <span className="confirm-remove-account__account__label">Public Address</span>
+ <span className="account_value">{ addressSummary(identity.address, 4, 4) }</span>
</div>
- <div className="modal-container__account__link">
+ <div className="confirm-remove-account__account__link">
<a
className=""
href={genAccountLink(identity.address, this.props.network)}
@@ -58,34 +58,27 @@ class ConfirmRemoveAccount extends Component {
const { t } = this.context
return (
- <div className="modal-container">
- <div className="modal-container__content">
- <div className="modal-container__title">
- { `${t('removeAccount')}` }?
- </div>
- { this.renderSelectedAccount() }
- <div className="modal-container__description">
+ <Modal
+ headerText={`${t('removeAccount')}?`}
+ onSubmit={() => this.handleRemove()}
+ onCancel={() => this.props.hideModal()}
+ submitText={t('remove')}
+ cancelText={t('nevermind')}
+ submitType="secondary"
+ >
+ <div>
+ { this.renderSelectedAccount() }
+ <div className="confirm-remove-account__description">
{ t('removeAccountDescription') }
- <a className="modal-container__link" rel="noopener noreferrer" target="_blank" href="https://consensys.zendesk.com/hc/en-us/articles/360004180111-What-are-imported-accounts-New-UI-">{ t('learnMore') }</a>
+ <a
+ className="confirm-remove-account__link"
+ rel="noopener noreferrer"
+ target="_blank" href="https://consensys.zendesk.com/hc/en-us/articles/360004180111-What-are-imported-accounts-New-UI-">
+ { t('learnMore') }
+ </a>
</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.handleRemove()}
- >
- { t('remove') }
- </Button>
- </div>
- </div>
+ </Modal>
)
}
}
diff --git a/ui/app/components/modals/confirm-remove-account/confirm-remove-account.container.js b/ui/app/components/modals/confirm-remove-account/confirm-remove-account.container.js
index 4b194c995..59d48400d 100644
--- a/ui/app/components/modals/confirm-remove-account/confirm-remove-account.container.js
+++ b/ui/app/components/modals/confirm-remove-account/confirm-remove-account.container.js
@@ -1,11 +1,12 @@
import { connect } from 'react-redux'
+import { compose } from 'recompose'
import ConfirmRemoveAccount from './confirm-remove-account.component'
+import withModalProps from '../../../higher-order-components/with-modal-props'
const { hideModal, removeAccount } = require('../../../actions')
const mapStateToProps = state => {
return {
- identity: state.appState.modal.modalState.props.identity,
network: state.metamask.network,
}
}
@@ -17,4 +18,7 @@ const mapDispatchToProps = dispatch => {
}
}
-export default connect(mapStateToProps, mapDispatchToProps)(ConfirmRemoveAccount)
+export default compose(
+ withModalProps,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmRemoveAccount)
diff --git a/ui/app/components/modals/confirm-remove-account/index.js b/ui/app/components/modals/confirm-remove-account/index.js
index 9763fbe05..ecb5f7790 100644
--- a/ui/app/components/modals/confirm-remove-account/index.js
+++ b/ui/app/components/modals/confirm-remove-account/index.js
@@ -1,2 +1 @@
-import ConfirmRemoveAccount from './confirm-remove-account.container'
-module.exports = ConfirmRemoveAccount
+export { default } from './confirm-remove-account.container'
diff --git a/ui/app/components/modals/confirm-remove-account/index.scss b/ui/app/components/modals/confirm-remove-account/index.scss
new file mode 100644
index 000000000..3be3a1967
--- /dev/null
+++ b/ui/app/components/modals/confirm-remove-account/index.scss
@@ -0,0 +1,58 @@
+.confirm-remove-account {
+ &__description {
+ text-align: center;
+ font-size: .875rem;
+ }
+
+ &__account {
+ border: 1px solid #b7b7b7;
+ border-radius: 4px;
+ padding: 10px;
+ display: flex;
+ margin-top: 10px;
+ margin-bottom: 20px;
+ width: 100%;
+
+ &__identicon {
+ margin-right: 10px;
+ }
+
+ &__name,
+ &__address {
+ margin-right: 10px;
+ font-size: 14px;
+ }
+
+ &__name {
+ width: 100px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ &__label {
+ font-size: 11px;
+ display: block;
+ color: #9b9b9b;
+ }
+
+ &__link {
+ margin-top: 14px;
+
+ img {
+ width: 15px;
+ height: 15px;
+ }
+ }
+
+ @media screen and (max-width: 575px) {
+ &__name {
+ width: 90px;
+ }
+ }
+ }
+
+ &__link {
+ color: #2f9ae0;
+ }
+} \ No newline at end of file
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
index 14a4da62a..f1a4542ac 100644
--- 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
@@ -1,8 +1,8 @@
-import React, { Component } from 'react'
+import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
-import Button from '../../button'
+import Modal, { ModalContent } from '../../modal'
-class ConfirmResetAccount extends Component {
+export default class ConfirmResetAccount extends PureComponent {
static propTypes = {
hideModal: PropTypes.func.isRequired,
resetAccount: PropTypes.func.isRequired,
@@ -12,7 +12,7 @@ class ConfirmResetAccount extends Component {
t: PropTypes.func,
}
- handleReset () {
+ handleReset = () => {
this.props.resetAccount()
.then(() => this.props.hideModal())
}
@@ -21,34 +21,18 @@ class ConfirmResetAccount extends Component {
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>
+ <Modal
+ onSubmit={this.handleReset}
+ onCancel={() => this.props.hideModal()}
+ submitText={t('reset')}
+ cancelText={t('nevermind')}
+ submitType="secondary"
+ >
+ <ModalContent
+ title={`${t('resetAccount')}?`}
+ description={t('resetAccountDescription')}
+ />
+ </Modal>
)
}
}
-
-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
index 9630a5593..c8a7b8478 100644
--- 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
@@ -1,13 +1,16 @@
import { connect } from 'react-redux'
+import { compose } from 'recompose'
+import withModalProps from '../../../higher-order-components/with-modal-props'
import ConfirmResetAccount from './confirm-reset-account.component'
-
-const { hideModal, resetAccount } = require('../../../actions')
+import { resetAccount } from '../../../actions'
const mapDispatchToProps = dispatch => {
return {
- hideModal: () => dispatch(hideModal()),
resetAccount: () => dispatch(resetAccount()),
}
}
-export default connect(null, mapDispatchToProps)(ConfirmResetAccount)
+export default compose(
+ withModalProps,
+ 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
index c812ffc55..ca4d9c5bf 100644
--- a/ui/app/components/modals/confirm-reset-account/index.js
+++ b/ui/app/components/modals/confirm-reset-account/index.js
@@ -1,2 +1 @@
-import ConfirmResetAccount from './confirm-reset-account.container'
-module.exports = ConfirmResetAccount
+export { default } from './confirm-reset-account.container'
diff --git a/ui/app/components/modals/index.scss b/ui/app/components/modals/index.scss
index 0acccf172..45453a582 100644
--- a/ui/app/components/modals/index.scss
+++ b/ui/app/components/modals/index.scss
@@ -1,108 +1,9 @@
-@import './customize-gas/index';
-
-@import './qr-scanner/index';
-
-.modal-container {
- width: 100%;
- height: 100%;
- background-color: #fff;
- display: flex;
- flex-flow: column;
- border-radius: 8px;
-
- &__title {
- font-size: 1.5rem;
- font-weight: 500;
- padding: 16px 0;
- text-align: center;
- }
-
- &__description {
- text-align: center;
- font-size: .875rem;
- }
-
- &__account {
- border: 1px solid #b7b7b7;
- border-radius: 4px;
- padding: 10px;
- display: flex;
- margin-top: 10px;
- margin-bottom: 20px;
- width: 100%;
-
- &__identicon {
- margin-right: 10px;
- }
-
- &__name,
- &__address {
- margin-right: 10px;
- font-size: 14px;
- }
+@import './cancel-transaction/index';
- &__name {
- width: 100px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
+@import './confirm-remove-account/index';
- &__label {
- font-size: 11px;
- display: block;
- color: #9b9b9b;
- }
-
- &__link {
- margin-top: 14px;
-
- img {
- width: 15px;
- height: 15px;
- }
- }
-
- @media screen and (max-width: 575px) {
- &__name {
- width: 90px;
- }
- }
- }
-
- &__link {
- color: #2f9ae0;
- }
-
- &__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;
+@import './customize-gas/index';
- &-button {
- min-width: 0;
- margin-right: 16px;
+@import './qr-scanner/index';
- &:last-of-type {
- margin-right: 0;
- }
- }
- }
-}
+@import './transaction-confirmed/index';
diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js
index 5dda50e52..2aec89326 100644
--- a/ui/app/components/modals/modal.js
+++ b/ui/app/components/modals/modal.js
@@ -19,14 +19,14 @@ 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('./confirm-reset-account')
-const ConfirmRemoveAccount = require('./confirm-remove-account')
const QRScanner = require('./qr-scanner')
-const TransactionConfirmed = require('./transaction-confirmed')
-const WelcomeBeta = require('./welcome-beta')
-const Notification = require('./notification')
+import ConfirmRemoveAccount from './confirm-remove-account'
+import ConfirmResetAccount from './confirm-reset-account'
+import TransactionConfirmed from './transaction-confirmed'
import ConfirmCustomizeGasModal from './customize-gas'
+import CancelTransaction from './cancel-transaction'
+import WelcomeBeta from './welcome-beta'
const modalContainerBaseStyle = {
transform: 'translate3d(-50%, 0, 0px)',
@@ -199,11 +199,7 @@ const MODALS = {
},
BETA_UI_NOTIFICATION_MODAL: {
- contents: [
- h(Notification, [
- h(WelcomeBeta),
- ]),
- ],
+ contents: h(WelcomeBeta),
mobileModalStyle: {
...modalContainerMobileStyle,
},
@@ -307,9 +303,7 @@ const MODALS = {
},
CONFIRM_CUSTOMIZE_GAS: {
- contents: [
- h(ConfirmCustomizeGasModal),
- ],
+ contents: h(ConfirmCustomizeGasModal),
mobileModalStyle: {
width: '100vw',
height: '100vh',
@@ -332,11 +326,7 @@ const MODALS = {
TRANSACTION_CONFIRMED: {
disableBackdropClick: true,
- contents: [
- h(Notification, [
- h(TransactionConfirmed),
- ]),
- ],
+ contents: h(TransactionConfirmed),
mobileModalStyle: {
...modalContainerMobileStyle,
},
@@ -347,6 +337,7 @@ const MODALS = {
borderRadius: '8px',
},
},
+
QR_SCANNER: {
contents: h(QRScanner),
mobileModalStyle: {
@@ -360,6 +351,19 @@ const MODALS = {
},
},
+ CANCEL_TRANSACTION: {
+ contents: h(CancelTransaction),
+ mobileModalStyle: {
+ ...modalContainerMobileStyle,
+ },
+ laptopModalStyle: {
+ ...modalContainerLaptopStyle,
+ },
+ contentStyle: {
+ borderRadius: '8px',
+ },
+ },
+
DEFAULT: {
contents: [],
mobileModalStyle: {},
diff --git a/ui/app/components/modals/notification/index.js b/ui/app/components/modals/notification/index.js
deleted file mode 100644
index d60a3129b..000000000
--- a/ui/app/components/modals/notification/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 1af2f3ca8..000000000
--- a/ui/app/components/modals/notification/notification.component.js
+++ /dev/null
@@ -1,30 +0,0 @@
-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
deleted file mode 100644
index 5b98714da..000000000
--- a/ui/app/components/modals/notification/notification.container.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { connect } from 'react-redux'
-import Notification from './notification.component'
-
-const { hideModal } = require('../../../actions')
-
-const mapStateToProps = state => {
- const { appState: { modal: { modalState: { props } } } } = state
- const { onHide } = props
- return {
- onHide,
- }
-}
-
-const mapDispatchToProps = dispatch => {
- return {
- hideModal: () => dispatch(hideModal()),
- }
-}
-
-const mergeProps = (stateProps, dispatchProps, ownProps) => {
- const { onHide, ...otherStateProps } = stateProps
- const { hideModal, ...otherDispatchProps } = dispatchProps
-
- return {
- ...otherStateProps,
- ...otherDispatchProps,
- ...ownProps,
- onHide: () => {
- hideModal()
-
- if (onHide && typeof onHide === 'function') {
- onHide()
- }
- },
- }
-}
-
-export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notification)
diff --git a/ui/app/components/modals/transaction-confirmed/index.js b/ui/app/components/modals/transaction-confirmed/index.js
index cee8da7f8..7776b969e 100644
--- a/ui/app/components/modals/transaction-confirmed/index.js
+++ b/ui/app/components/modals/transaction-confirmed/index.js
@@ -1,2 +1 @@
-import TransactionConfirmed from './transaction-confirmed.component'
-module.exports = TransactionConfirmed
+export { default } from './transaction-confirmed.container'
diff --git a/ui/app/components/modals/transaction-confirmed/index.scss b/ui/app/components/modals/transaction-confirmed/index.scss
new file mode 100644
index 000000000..c97371fb6
--- /dev/null
+++ b/ui/app/components/modals/transaction-confirmed/index.scss
@@ -0,0 +1,22 @@
+.transaction-confirmed {
+ &__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: 16px;
+ }
+}
diff --git a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js
index c1c8a2976..0a98eb1a1 100644
--- a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js
+++ b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.component.js
@@ -1,24 +1,45 @@
-import React from 'react'
+import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
+import Modal from '../../modal'
-const TransactionConfirmed = (props, context) => {
- const { t } = context
+export default class TransactionConfirmed extends PureComponent {
+ static contextTypes = {
+ t: PropTypes.func,
+ }
- 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>
- )
-}
+ static propTypes = {
+ onSubmit: PropTypes.func,
+ hideModal: PropTypes.func,
+ }
-TransactionConfirmed.contextTypes = {
- t: PropTypes.func,
-}
+ handleSubmit = () => {
+ const { hideModal, onSubmit } = this.props
+
+ hideModal()
-export default TransactionConfirmed
+ if (onSubmit && typeof onSubmit === 'function') {
+ onSubmit()
+ }
+ }
+
+ render () {
+ const { t } = this.context
+
+ return (
+ <Modal
+ onSubmit={this.handleSubmit}
+ submitText={t('ok')}
+ >
+ <div className="transaction-confirmed__content">
+ <img src="images/check-icon.svg" />
+ <div className="transaction-confirmed__title">
+ { `${t('confirmed')}!` }
+ </div>
+ <div className="transaction-confirmed__description">
+ { t('initialTransactionConfirmed') }
+ </div>
+ </div>
+ </Modal>
+ )
+ }
+}
diff --git a/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js
new file mode 100644
index 000000000..d4e39681a
--- /dev/null
+++ b/ui/app/components/modals/transaction-confirmed/transaction-confirmed.container.js
@@ -0,0 +1,4 @@
+import TransactionConfirmed from './transaction-confirmed.component'
+import withModalProps from '../../../higher-order-components/with-modal-props'
+
+export default withModalProps(TransactionConfirmed)
diff --git a/ui/app/components/modals/welcome-beta/index.js b/ui/app/components/modals/welcome-beta/index.js
index 515c9cdaf..49e45b9d7 100644
--- a/ui/app/components/modals/welcome-beta/index.js
+++ b/ui/app/components/modals/welcome-beta/index.js
@@ -1,2 +1 @@
-import WelcomeBeta from './welcome-beta.component'
-module.exports = WelcomeBeta
+export { default } from './welcome-beta.container'
diff --git a/ui/app/components/modals/welcome-beta/welcome-beta.component.js b/ui/app/components/modals/welcome-beta/welcome-beta.component.js
index 61571723a..ef1799164 100644
--- a/ui/app/components/modals/welcome-beta/welcome-beta.component.js
+++ b/ui/app/components/modals/welcome-beta/welcome-beta.component.js
@@ -1,18 +1,21 @@
import React from 'react'
import PropTypes from 'prop-types'
+import Modal, { ModalContent } from '../../modal'
const TransactionConfirmed = (props, context) => {
const { t } = context
+ const { hideModal } = props
return (
- <div className="modal-container__content">
- <div className="modal-container__title">
- { `${t('uiWelcome')}` }
- </div>
- <div className="modal-container__description">
- { t('uiWelcomeMessage') }
- </div>
- </div>
+ <Modal
+ onSubmit={() => hideModal()}
+ submitText={t('ok')}
+ >
+ <ModalContent
+ title={t('uiWelcome')}
+ description={t('uiWelcomeMessage')}
+ />
+ </Modal>
)
}
@@ -20,4 +23,8 @@ TransactionConfirmed.contextTypes = {
t: PropTypes.func,
}
+TransactionConfirmed.propTypes = {
+ hideModal: PropTypes.func,
+}
+
export default TransactionConfirmed
diff --git a/ui/app/components/modals/welcome-beta/welcome-beta.container.js b/ui/app/components/modals/welcome-beta/welcome-beta.container.js
new file mode 100644
index 000000000..c5123ad47
--- /dev/null
+++ b/ui/app/components/modals/welcome-beta/welcome-beta.container.js
@@ -0,0 +1,4 @@
+import WelcomeBeta from './welcome-beta.component'
+import withModalProps from '../../../higher-order-components/with-modal-props'
+
+export default withModalProps(WelcomeBeta)
diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
index 56cfbccc8..40d8faf50 100644
--- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
+++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
@@ -8,6 +8,7 @@ import {
INSUFFICIENT_FUNDS_ERROR_KEY,
TRANSACTION_ERROR_KEY,
} from '../../../constants/error-keys'
+import { CONFIRMED_STATUS, DROPPED_STATUS } from '../../../constants/transactions'
export default class ConfirmTransactionBase extends Component {
static contextTypes = {
@@ -85,9 +86,9 @@ export default class ConfirmTransactionBase extends Component {
clearConfirmTransaction,
} = this.props
- if (transactionStatus === 'dropped') {
+ if (transactionStatus === DROPPED_STATUS || transactionStatus === CONFIRMED_STATUS) {
showTransactionConfirmedModal({
- onHide: () => {
+ onSubmit: () => {
clearConfirmTransaction()
history.push(DEFAULT_ROUTE)
},
diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
index 8f54c8040..ae31eba17 100644
--- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
+++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
@@ -97,8 +97,8 @@ const mapDispatchToProps = dispatch => {
return {
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
clearSend: () => dispatch(clearSend()),
- showTransactionConfirmedModal: ({ onHide }) => {
- return dispatch(showModal({ name: 'TRANSACTION_CONFIRMED', onHide }))
+ showTransactionConfirmedModal: ({ onSubmit }) => {
+ return dispatch(showModal({ name: 'TRANSACTION_CONFIRMED', onSubmit }))
},
showCustomizeGasModal: ({ txData, onSubmit, validate }) => {
return dispatch(showModal({ name: 'CONFIRM_CUSTOMIZE_GAS', txData, onSubmit, validate }))
diff --git a/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js b/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js
index f65ff4d55..13cb51349 100644
--- a/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js
+++ b/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js
@@ -13,7 +13,9 @@ export default class TransactionListItemDetails extends PureComponent {
}
static propTypes = {
+ onCancel: PropTypes.func,
onRetry: PropTypes.func,
+ showCancel: PropTypes.bool,
showRetry: PropTypes.bool,
transaction: PropTypes.object,
}
@@ -27,6 +29,13 @@ export default class TransactionListItemDetails extends PureComponent {
this.setState({ showTransactionDetails: true })
}
+ handleCancel = event => {
+ const { onCancel } = this.props
+
+ event.stopPropagation()
+ onCancel()
+ }
+
handleRetry = event => {
const { onRetry } = this.props
@@ -36,7 +45,7 @@ export default class TransactionListItemDetails extends PureComponent {
render () {
const { t } = this.context
- const { transaction, showRetry } = this.props
+ const { transaction, showCancel, showRetry } = this.props
const { txParams: { to, from } = {} } = transaction
return (
@@ -55,6 +64,17 @@ export default class TransactionListItemDetails extends PureComponent {
</Button>
)
}
+ {
+ showCancel && (
+ <Button
+ type="raised"
+ onClick={this.handleCancel}
+ className="transaction-list-item-details__header-button"
+ >
+ { t('cancel') }
+ </Button>
+ )
+ }
<Button
type="raised"
onClick={this.handleEtherscanClick}
diff --git a/ui/app/components/transaction-list-item/transaction-list-item.component.js b/ui/app/components/transaction-list-item/transaction-list-item.component.js
index e590e96e0..72389c95b 100644
--- a/ui/app/components/transaction-list-item/transaction-list-item.component.js
+++ b/ui/app/components/transaction-list-item/transaction-list-item.component.js
@@ -12,17 +12,19 @@ import { ETH } from '../../constants/common'
export default class TransactionListItem extends PureComponent {
static propTypes = {
+ assetImages: PropTypes.object,
history: PropTypes.object,
- transaction: PropTypes.object,
- value: PropTypes.string,
methodData: PropTypes.object,
- showRetry: PropTypes.bool,
+ nonceAndDate: PropTypes.string,
retryTransaction: PropTypes.func,
setSelectedToken: PropTypes.func,
- nonceAndDate: PropTypes.string,
+ showCancelModal: PropTypes.func,
+ showCancel: PropTypes.bool,
+ showRetry: PropTypes.bool,
token: PropTypes.object,
- assetImages: PropTypes.object,
tokenData: PropTypes.object,
+ transaction: PropTypes.object,
+ value: PropTypes.string,
}
state = {
@@ -42,6 +44,11 @@ export default class TransactionListItem extends PureComponent {
this.setState({ showTransactionDetails: !showTransactionDetails })
}
+ handleCancel = () => {
+ const { transaction: { id, txParams: { gasPrice } } = {}, showCancelModal } = this.props
+ showCancelModal(id, gasPrice)
+ }
+
handleRetry = () => {
const {
transaction: { txParams: { to } = {} },
@@ -100,12 +107,13 @@ export default class TransactionListItem extends PureComponent {
render () {
const {
- transaction,
+ assetImages,
methodData,
- showRetry,
nonceAndDate,
- assetImages,
+ showCancel,
+ showRetry,
tokenData,
+ transaction,
} = this.props
const { txParams = {} } = transaction
const { showTransactionDetails } = this.state
@@ -153,8 +161,10 @@ export default class TransactionListItem extends PureComponent {
<div className="transaction-list-item__details-container">
<TransactionListItemDetails
transaction={transaction}
- showRetry={showRetry && methodData.done}
onRetry={this.handleRetry}
+ showRetry={showRetry && methodData.done}
+ onCancel={this.handleCancel}
+ showCancel={showCancel}
/>
</div>
)
diff --git a/ui/app/components/transaction-list-item/transaction-list-item.container.js b/ui/app/components/transaction-list-item/transaction-list-item.container.js
index 3db9d40ec..62ed7a73f 100644
--- a/ui/app/components/transaction-list-item/transaction-list-item.container.js
+++ b/ui/app/components/transaction-list-item/transaction-list-item.container.js
@@ -3,7 +3,7 @@ import { withRouter } from 'react-router-dom'
import { compose } from 'recompose'
import withMethodData from '../../higher-order-components/with-method-data'
import TransactionListItem from './transaction-list-item.component'
-import { setSelectedToken, retryTransaction } from '../../actions'
+import { setSelectedToken, retryTransaction, showModal } from '../../actions'
import { hexToDecimal } from '../../helpers/conversions.util'
import { getTokenData } from '../../helpers/transactions.util'
import { formatDate } from '../../util'
@@ -25,6 +25,9 @@ const mapDispatchToProps = dispatch => {
return {
setSelectedToken: tokenAddress => dispatch(setSelectedToken(tokenAddress)),
retryTransaction: transactionId => dispatch(retryTransaction(transactionId)),
+ showCancelModal: (transactionId, originalGasPrice) => {
+ return dispatch(showModal({ name: 'CANCEL_TRANSACTION', transactionId, originalGasPrice }))
+ },
}
}
diff --git a/ui/app/components/transaction-list/transaction-list.component.js b/ui/app/components/transaction-list/transaction-list.component.js
index c864fea3b..eef60186d 100644
--- a/ui/app/components/transaction-list/transaction-list.component.js
+++ b/ui/app/components/transaction-list/transaction-list.component.js
@@ -56,7 +56,7 @@ export default class TransactionList extends PureComponent {
</div>
{
pendingTransactions.map((transaction, index) => (
- this.renderTransaction(transaction, index)
+ this.renderTransaction(transaction, index, true)
))
}
</div>
@@ -78,7 +78,7 @@ export default class TransactionList extends PureComponent {
)
}
- renderTransaction (transaction, index) {
+ renderTransaction (transaction, index, showCancel) {
const { selectedToken, assetImages } = this.props
return transaction.key === TRANSACTION_TYPE_SHAPESHIFT
@@ -92,6 +92,7 @@ export default class TransactionList extends PureComponent {
transaction={transaction}
key={transaction.id}
showRetry={this.shouldShowRetry(transaction)}
+ showCancel={showCancel}
token={selectedToken}
assetImages={assetImages}
/>
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 112ea6bca..0784a872e 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -104,7 +104,7 @@ ConfirmTxScreen.prototype.componentDidUpdate = function (prevProps) {
if (prevTx && prevTx.status === 'dropped') {
this.props.dispatch(actions.showModal({
name: 'TRANSACTION_CONFIRMED',
- onHide: () => history.push(DEFAULT_ROUTE),
+ onSubmit: () => history.push(DEFAULT_ROUTE),
}))
return
diff --git a/ui/app/constants/transactions.js b/ui/app/constants/transactions.js
index df6c4c8a4..2dc061091 100644
--- a/ui/app/constants/transactions.js
+++ b/ui/app/constants/transactions.js
@@ -18,5 +18,6 @@ export const SEND_TOKEN_ACTION_KEY = 'sentTokens'
export const TRANSFER_FROM_ACTION_KEY = 'transferFrom'
export const SIGNATURE_REQUEST_KEY = 'signatureRequest'
export const UNKNOWN_FUNCTION_KEY = 'unknownFunction'
+export const CANCEL_ATTEMPT_ACTION_KEY = 'cancelAttempt'
export const TRANSACTION_TYPE_SHAPESHIFT = 'shapeshift'
diff --git a/ui/app/helpers/conversions.util.js b/ui/app/helpers/conversions.util.js
index 5204faa1f..20ef9e35b 100644
--- a/ui/app/helpers/conversions.util.js
+++ b/ui/app/helpers/conversions.util.js
@@ -1,6 +1,11 @@
+import ethUtil from 'ethereumjs-util'
import { conversionUtil } from '../conversion-util'
import { ETH, GWEI, WEI } from '../constants/common'
+export function bnToHex (inputBn) {
+ return ethUtil.addHexPrefix(inputBn.toString(16))
+}
+
export function hexToDecimal (hexValue) {
return conversionUtil(hexValue, {
fromNumericBase: 'hex',
@@ -8,6 +13,13 @@ export function hexToDecimal (hexValue) {
})
}
+export function decimalToHex (decimal) {
+ return conversionUtil(decimal, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ })
+}
+
export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDecimals = 6 }) {
const denominations = [ETH, GWEI, WEI]
diff --git a/ui/app/helpers/transactions.util.js b/ui/app/helpers/transactions.util.js
index 54bb3bcb9..8b87bb538 100644
--- a/ui/app/helpers/transactions.util.js
+++ b/ui/app/helpers/transactions.util.js
@@ -14,6 +14,7 @@ import {
TRANSFER_FROM_ACTION_KEY,
SIGNATURE_REQUEST_KEY,
UNKNOWN_FUNCTION_KEY,
+ CANCEL_ATTEMPT_ACTION_KEY,
} from '../constants/transactions'
import { addCurrencies } from '../conversion-util'
@@ -44,7 +45,11 @@ export function isConfirmDeployContract (txData = {}) {
}
export async function getTransactionActionKey (transaction, methodData) {
- const { txParams: { data, to } = {}, msgParams } = transaction
+ const { txParams: { data, to } = {}, msgParams, type } = transaction
+
+ if (type === 'cancel') {
+ return CANCEL_ATTEMPT_ACTION_KEY
+ }
if (msgParams) {
return SIGNATURE_REQUEST_KEY