diff options
Diffstat (limited to 'ui')
29 files changed, 513 insertions, 192 deletions
diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js index 9cefcfa77..dd5dfad22 100644 --- a/ui/app/accounts/import/json.js +++ b/ui/app/accounts/import/json.js @@ -81,6 +81,12 @@ JsonImportSubview.prototype.createKeyringOnEnter = function (event) { JsonImportSubview.prototype.createNewKeychain = function () { const state = this.state + + if (!state) { + const message = 'You must select a valid file to import.' + return this.props.dispatch(actions.displayWarning(message)) + } + const { fileContents } = state if (!fileContents) { diff --git a/ui/app/actions.js b/ui/app/actions.js index c52b3cf93..4bc1f379e 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -47,6 +47,8 @@ var actions = { SHOW_RESTORE_VAULT: 'SHOW_RESTORE_VAULT', FORGOT_PASSWORD: 'FORGOT_PASSWORD', forgotPassword: forgotPassword, + markPasswordForgotten, + unMarkPasswordForgotten, SHOW_INIT_MENU: 'SHOW_INIT_MENU', SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED', SHOW_INFO_PAGE: 'SHOW_INFO_PAGE', @@ -70,12 +72,14 @@ var actions = { addNewAccount, NEW_ACCOUNT_SCREEN: 'NEW_ACCOUNT_SCREEN', navigateToNewAccountScreen, + resetAccount, showNewVaultSeed: showNewVaultSeed, showInfoPage: showInfoPage, // seed recovery actions REVEAL_SEED_CONFIRMATION: 'REVEAL_SEED_CONFIRMATION', revealSeedConfirmation: revealSeedConfirmation, requestRevealSeed: requestRevealSeed, + // unlock screen UNLOCK_IN_PROGRESS: 'UNLOCK_IN_PROGRESS', UNLOCK_FAILED: 'UNLOCK_FAILED', @@ -253,6 +257,9 @@ var actions = { updateFeatureFlags, UPDATE_FEATURE_FLAGS: 'UPDATE_FEATURE_FLAGS', + setMouseUserState, + SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE', + // Network setNetworkEndpoints, updateNetworkEndpointType, @@ -399,6 +406,20 @@ function requestRevealSeed (password) { } } +function resetAccount () { + return (dispatch) => { + background.resetAccount((err, account) => { + dispatch(actions.hideLoadingIndication()) + if (err) { + dispatch(actions.displayWarning(err.message)) + } + + log.info('Transaction history reset for ' + account) + dispatch(actions.showAccountsPage()) + }) + } +} + function addNewKeyring (type, opts) { return (dispatch) => { dispatch(actions.showLoadingIndication()) @@ -819,6 +840,26 @@ function showRestoreVault () { } } +function markPasswordForgotten () { + return (dispatch) => { + return background.markPasswordForgotten(() => { + dispatch(actions.hideLoadingIndication()) + dispatch(actions.forgotPassword()) + forceUpdateMetamaskState(dispatch) + }) + } +} + +function unMarkPasswordForgotten () { + return (dispatch) => { + return background.unMarkPasswordForgotten(() => { + dispatch(actions.hideLoadingIndication()) + dispatch(actions.forgotPassword()) + forceUpdateMetamaskState(dispatch) + }) + } +} + function forgotPassword () { return { type: actions.FORGOT_PASSWORD, @@ -1621,6 +1662,13 @@ function updateFeatureFlags (updatedFeatureFlags) { } } +function setMouseUserState (isMouseUser) { + return { + type: actions.SET_MOUSE_USER_STATE, + value: isMouseUser, + } +} + // Call Background Then Update // // A function generator for a common pattern wherein: diff --git a/ui/app/app.js b/ui/app/app.js index df9eab03c..5ffd263d1 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -9,7 +9,7 @@ const classnames = require('classnames') const MascaraFirstTime = require('../../mascara/src/app/first-time').default const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default // init -const InitializeMenuScreen = require('./first-time/init-menu') +const InitializeMenuScreen = MascaraFirstTime const NewKeyChainScreen = require('./new-keychain') // accounts const MainContainer = require('./main-container') @@ -74,17 +74,20 @@ function mapStateToProps (state) { transForward: state.appState.transForward, isMascara: state.metamask.isMascara, isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized), + isPopup: state.metamask.isPopup, seedWords: state.metamask.seedWords, unapprovedTxs: state.metamask.unapprovedTxs, unapprovedMsgs: state.metamask.unapprovedMsgs, menuOpen: state.appState.menuOpen, network: state.metamask.network, provider: state.metamask.provider, - forgottenPassword: state.appState.forgottenPassword, + forgottenPassword: state.metamask.forgottenPassword, lastUnreadNotice: state.metamask.lastUnreadNotice, lostAccounts: state.metamask.lostAccounts, frequentRpcList: state.metamask.frequentRpcList || [], currentCurrency: state.metamask.currentCurrency, + isMouseUser: state.appState.isMouseUser, + betaUI: state.metamask.featureFlags.betaUI, // state needed to get account dropdown temporarily rendering from app bar identities, @@ -101,6 +104,7 @@ function mapDispatchToProps (dispatch, ownProps) { hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()), setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')), toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()), + setMouseUserState: (isMouseUser) => dispatch(actions.setMouseUserState(isMouseUser)), } } @@ -112,7 +116,13 @@ App.prototype.componentWillMount = function () { App.prototype.render = function () { var props = this.props - const { isLoading, loadingMessage, network } = props + const { + isLoading, + loadingMessage, + network, + isMouseUser, + setMouseUserState, + } = props const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config' const loadMessage = loadingMessage || isLoadingNetwork ? `Connecting to ${this.getNetworkName()}` : null @@ -120,11 +130,19 @@ App.prototype.render = function () { return ( h('.flex-column.full-height', { + className: classnames({ 'mouse-user-styles': isMouseUser }), style: { overflowX: 'hidden', position: 'relative', alignItems: 'center', }, + tabIndex: '0', + onClick: () => setMouseUserState(true), + onKeyDown: (e) => { + if (e.keyCode === 9) { + setMouseUserState(false) + } + }, }, [ // global modal @@ -335,9 +353,9 @@ App.prototype.renderBackButton = function (style, justArrow = false) { App.prototype.renderPrimary = function () { log.debug('rendering primary') var props = this.props - const {isMascara, isOnboarding} = props + const {isMascara, isOnboarding, betaUI} = props - if (isMascara && isOnboarding) { + if ((isMascara || betaUI) && isOnboarding && !props.isPopup) { return h(MascaraFirstTime) } @@ -358,20 +376,12 @@ App.prototype.renderPrimary = function () { }) } - // show initialize screen - if (!props.isInitialized || props.forgottenPassword) { - // show current view - log.debug('rendering an initialize screen') - switch (props.currentView.name) { - - case 'restoreVault': - log.debug('rendering restore vault screen') - return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'}) - - default: - log.debug('rendering menu screen') - return h(InitializeMenuScreen, {key: 'menuScreenInit'}) - } + if (props.isInitialized && props.forgottenPassword) { + log.debug('rendering restore vault screen') + return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'}) + } else if (!props.isInitialized) { + log.debug('rendering menu screen') + return h(InitializeMenuScreen, {key: 'menuScreenInit'}) } // show unlock screen diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index aeb8a0b38..1a0103d4f 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -80,23 +80,23 @@ AccountMenu.prototype.render = function () { h(Divider), h(Item, { onClick: () => showNewAccountPage('CREATE'), - icon: h('img', { src: 'images/plus-btn-white.svg' }), + icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }), text: 'Create Account', }), h(Item, { onClick: () => showNewAccountPage('IMPORT'), - icon: h('img', { src: 'images/import-account.svg' }), + icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }), text: 'Import Account', }), h(Divider), h(Item, { onClick: showInfoPage, - icon: h('img', { src: 'images/mm-info-icon.svg' }), + icon: h('img.account-menu__item-icon', { src: 'images/mm-info-icon.svg' }), text: 'Info & Help', }), h(Item, { onClick: showConfigPage, - icon: h('img', { src: 'images/settings.svg' }), + icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }), text: 'Settings', }), ]) diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index afb2a2175..97fe38292 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -18,6 +18,7 @@ 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 accountModalStyle = { mobileModalStyle: { @@ -202,6 +203,18 @@ const MODALS = { }, }, + CONFIRM_RESET_ACCOUNT: { + contents: h(ConfirmResetAccount), + mobileModalStyle: { + width: '95%', + top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh', + }, + laptopModalStyle: { + width: '473px', + top: 'calc(33% + 45px)', + }, + }, + NEW_ACCOUNT: { contents: [ h(NewAccountModal, {}, []), diff --git a/ui/app/components/modals/notification-modal.js b/ui/app/components/modals/notification-modal.js index 239144b0c..621a974d0 100644 --- a/ui/app/components/modals/notification-modal.js +++ b/ui/app/components/modals/notification-modal.js @@ -9,26 +9,47 @@ class NotificationModal extends Component { const { header, message, + showCancelButton = false, + showConfirmButton = false, + hideModal, + onConfirm, } = this.props + const showButtons = showCancelButton || showConfirmButton + return h('div', [ - h('div.notification-modal-wrapper', { + h('div.notification-modal__wrapper', { }, [ - h('div.notification-modal-header', {}, [ + h('div.notification-modal__header', {}, [ header, ]), - h('div.notification-modal-message-wrapper', {}, [ - h('div.notification-modal-message', {}, [ + h('div.notification-modal__message-wrapper', {}, [ + h('div.notification-modal__message', {}, [ message, ]), ]), h('div.modal-close-x', { - onClick: this.props.hideModal, + onClick: hideModal, }), + showButtons && h('div.notification-modal__buttons', [ + + showCancelButton && h('div.btn-cancel.notification-modal__buttons__btn', { + onClick: hideModal, + }, 'Cancel'), + + showConfirmButton && h('div.btn-clear.notification-modal__buttons__btn', { + onClick: () => { + onConfirm() + hideModal() + }, + }, 'Confirm'), + + ]), + ]), ]) } @@ -37,7 +58,10 @@ class NotificationModal extends Component { NotificationModal.propTypes = { hideModal: PropTypes.func, header: PropTypes.string, - message: PropTypes.string, + message: PropTypes.node, + showCancelButton: PropTypes.bool, + showConfirmButton: PropTypes.bool, + onConfirm: PropTypes.func, } const mapDispatchToProps = dispatch => { diff --git a/ui/app/components/modals/notification-modals/confirm-reset-account.js b/ui/app/components/modals/notification-modals/confirm-reset-account.js new file mode 100644 index 000000000..e1bc91b24 --- /dev/null +++ b/ui/app/components/modals/notification-modals/confirm-reset-account.js @@ -0,0 +1,46 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') +const { connect } = require('react-redux') +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/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 652300c94..3f8d9c28f 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -213,17 +213,15 @@ ConfirmSendEther.prototype.render = function () { this.inputs = [] return ( - h('div.confirm-screen-container.confirm-send-ether', { - style: { minWidth: '355px' }, - }, [ + h('div.confirm-screen-container.confirm-send-ether', [ // Main Send token Card - h('div.confirm-screen-wrapper.flex-column.flex-grow', [ - h('h3.flex-center.confirm-screen-header', [ - h('button.btn-clear.confirm-screen-back-button', { + h('div.page-container', [ + h('div.page-container__header', [ + h('button.confirm-screen-back-button', { onClick: () => editTransaction(txMeta), - }, 'EDIT'), - h('div.confirm-screen-title', 'Confirm Transaction'), - h('div.confirm-screen-header-tip'), + }, 'Edit'), + h('div.page-container__title', 'Confirm'), + h('div.page-container__subtitle', `Please review your transaction.`), ]), h('div.flex-row.flex-center.confirm-screen-identicons', [ h('div.confirm-screen-account-wrapper', [ diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index ad489c3e9..e4b0c186a 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -308,17 +308,15 @@ ConfirmSendToken.prototype.render = function () { this.inputs = [] return ( - h('div.confirm-screen-container.confirm-send-token', { - style: { minWidth: '355px' }, - }, [ + h('div.confirm-screen-container.confirm-send-token', [ // Main Send token Card - h('div.confirm-screen-wrapper.flex-column.flex-grow', [ - h('h3.flex-center.confirm-screen-header', [ - h('button.btn-clear.confirm-screen-back-button', { + h('div.page-container', [ + h('div.page-container__header', [ + h('button.confirm-screen-back-button', { onClick: () => editTransaction(txMeta), - }, 'EDIT'), - h('div.confirm-screen-title', 'Confirm Transaction'), - h('div.confirm-screen-header-tip'), + }, 'Edit'), + h('div.page-container__title', 'Confirm'), + h('div.page-container__subtitle', `Please review your transaction.`), ]), h('div.flex-row.flex-center.confirm-screen-identicons', [ h('div.confirm-screen-account-wrapper', [ diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js index 111a77df4..017bf9f0c 100644 --- a/ui/app/components/shift-list-item.js +++ b/ui/app/components/shift-list-item.js @@ -29,40 +29,35 @@ function ShiftListItem () { } ShiftListItem.prototype.render = function () { - const { selectedAddress, receivingAddress } = this.props - return ( - selectedAddress === receivingAddress - ? h('div.tx-list-item.tx-list-clickable', { + return h('div.tx-list-item.tx-list-clickable', { + style: { + paddingTop: '20px', + paddingBottom: '20px', + justifyContent: 'space-around', + alignItems: 'center', + }, + }, [ + h('div', { + style: { + width: '0px', + position: 'relative', + bottom: '19px', + }, + }, [ + h('img', { + src: 'https://info.shapeshift.io/sites/default/files/logo.png', style: { - paddingTop: '20px', - paddingBottom: '20px', - justifyContent: 'space-around', - alignItems: 'center', + height: '35px', + width: '132px', + position: 'absolute', + clip: 'rect(0px,23px,34px,0px)', }, - }, [ - h('div', { - style: { - width: '0px', - position: 'relative', - bottom: '19px', - }, - }, [ - h('img', { - src: 'https://info.shapeshift.io/sites/default/files/logo.png', - style: { - height: '35px', - width: '132px', - position: 'absolute', - clip: 'rect(0px,23px,34px,0px)', - }, - }), - ]), + }), + ]), - this.renderInfo(), - this.renderUtilComponents(), - ]) - : null - ) + this.renderInfo(), + this.renderUtilComponents(), + ]) } function formatDate (date) { diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js index 677f22a75..0332fde88 100644 --- a/ui/app/components/token-cell.js +++ b/ui/app/components/token-cell.js @@ -111,7 +111,7 @@ TokenCell.prototype.render = function () { network, }), - h('div.token-list-item__balance-wrapper', null, [ + h('div.token-list-item__balance-ellipsis', null, [ h('div.token-list-item__balance-wrapper', null, [ h('h3.token-list-item__token-balance', `${string || 0} ${symbol}`), diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js index 84cd0f093..1729e6a6f 100644 --- a/ui/app/components/tx-list.js +++ b/ui/app/components/tx-list.js @@ -50,6 +50,7 @@ TxList.prototype.render = function () { TxList.prototype.renderTransaction = function () { const { txsToRender, conversionRate } = this.props + return txsToRender.length ? txsToRender.map((transaction, i) => this.renderTransactionListItem(transaction, conversionRate, i)) : [h( @@ -65,11 +66,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa // refer to transaction-list.js:line 58 if (transaction.key === 'shapeshift') { - return h('div', { - key: `shapeshift${index}`, - }, [ - h(ShiftListItem, transaction), - ]) + return h(ShiftListItem, { ...transaction, key: `shapeshift${index}` }) } const props = { diff --git a/ui/app/css/itcss/base/index.scss b/ui/app/css/itcss/base/index.scss index baa6ea037..1475e8bb5 100644 --- a/ui/app/css/itcss/base/index.scss +++ b/ui/app/css/itcss/base/index.scss @@ -1 +1,7 @@ // Base + +.mouse-user-styles { + button:focus { + outline: 0; + } +} diff --git a/ui/app/css/itcss/components/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss index e16d2e024..8ad7481c7 100644 --- a/ui/app/css/itcss/components/account-menu.scss +++ b/ui/app/css/itcss/components/account-menu.scss @@ -43,7 +43,7 @@ font-weight: 300; } - img { + &__item-icon { width: 16px; height: 16px; } diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss index 255f66e66..878495290 100644 --- a/ui/app/css/itcss/components/confirm.scss +++ b/ui/app/css/itcss/components/confirm.scss @@ -103,15 +103,13 @@ } .confirm-screen-back-button { - background: transparent; - left: 24px; + color: $curious-blue; + font-family: Roboto; + font-size: 1rem; position: absolute; - padding: 6px 12px; - font-size: .7rem; - - @media screen and (max-width: $break-small) { - margin-right: 12px; - } + top: 38px; + right: 38px; + background: none; } .confirm-screen-account-wrapper { diff --git a/ui/app/css/itcss/components/currency-display.scss b/ui/app/css/itcss/components/currency-display.scss index 9459629b6..e043c1966 100644 --- a/ui/app/css/itcss/components/currency-display.scss +++ b/ui/app/css/itcss/components/currency-display.scss @@ -4,7 +4,7 @@ border: 1px solid $alto; border-radius: 4px; background-color: $white; - color: $dusty-gray; + color: $scorpion; font-family: Roboto; font-size: 16px; font-weight: 300; @@ -52,5 +52,6 @@ &__currency-symbol { margin-top: 1px; + color: $scorpion; } }
\ No newline at end of file diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss index 5bca4a07d..919e1793b 100644 --- a/ui/app/css/itcss/components/modal.scss +++ b/ui/app/css/itcss/components/modal.scss @@ -547,38 +547,54 @@ //Notification Modal -.notification-modal-wrapper { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - position: relative; - border: 1px solid $alto; - box-shadow: 0 0 2px 2px $alto; - font-family: Roboto; -} +.notification-modal { -.notification-modal-header { - background: $wild-sand; - width: 100%; - display: flex; - justify-content: center; - padding: 30px; - font-size: 22px; - color: $nile-blue; - height: 79px; -} + &__wrapper { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + position: relative; + border: 1px solid $alto; + box-shadow: 0 0 2px 2px $alto; + font-family: Roboto; + } -.notification-modal-message { - padding: 20px; -} + &__header { + background: $wild-sand; + width: 100%; + display: flex; + justify-content: center; + padding: 30px; + font-size: 22px; + color: $nile-blue; + height: 79px; + } -.notification-modal-message { - width: 100%; - display: flex; - justify-content: center; - font-size: 17px; - color: $nile-blue; + &__message { + padding: 20px; + width: 100%; + display: flex; + justify-content: center; + font-size: 17px; + color: $nile-blue; + } + + &__buttons { + display: flex; + justify-content: space-evenly; + width: 100%; + margin-bottom: 24px; + padding: 0px 42px; + + &__btn { + cursor: pointer; + } + } + + &__link { + color: $curious-blue; + } } // Deposit Ether Modal diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index a5e4523b9..73faebe8b 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -105,6 +105,7 @@ $wallet-view-bg: $alabaster; &__tooltip { display: flex; justify-content: center; + align-items: center; padding: 24px; } diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index 7a6e2823b..bb17e53cd 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -533,7 +533,6 @@ @media screen and (max-width: $break-small) { padding: 13px 0; margin: 0; - height: 0; overflow-y: auto; flex: 1 1 auto; } @@ -558,6 +557,25 @@ &__form-field { flex: 1 1 auto; + + .currency-display { + color: $tundora; + + &__currency-symbol { + color: $tundora; + } + + &__converted-value, + &__converted-currency { + color: $tundora; + } + } + + .account-list-item { + &__account-secondary-balance { + color: $tundora; + } + } } &__form-label { @@ -566,6 +584,7 @@ font-size: 16px; line-height: 22px; width: 88px; + font-weight: 400; } &__from-dropdown { @@ -621,7 +640,7 @@ border: 1px solid $alto; border-radius: 4px; background-color: $white; - color: $dusty-gray; + color: $tundora; padding: 10px; font-family: Roboto; font-size: 16px; diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index e90418c97..9dc4f1055 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -51,7 +51,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( &__balance-ellipsis { display: flex; align-items: center; - justify-content: space-around; + width: 100%; } &__ellipsis { diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss index 9d55324e3..9b3d7475b 100644 --- a/ui/app/css/itcss/generic/index.scss +++ b/ui/app/css/itcss/generic/index.scss @@ -69,3 +69,136 @@ textarea.large-input { input.large-input { height: 36px; } + +.page-container { + width: 400px; + background-color: $white; + box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08); + z-index: 25; + display: flex; + flex-flow: column; + + &__header { + display: flex; + flex-flow: column; + border-bottom: 1px solid $geyser; + padding: 1.15rem 0.95rem; + flex: 0 0 auto; + background: $alabaster; + position: relative; + } + + &__header-close::after { + content: '\00D7'; + font-size: 40px; + color: $tundora; + position: absolute; + top: 21.5px; + right: 28.5px; + cursor: pointer; + } + + &__footer { + display: flex; + flex-flow: row; + justify-content: center; + border-top: 1px solid $geyser; + padding: 1.6rem; + flex: 0 0 auto; + + .btn-clear, + .btn-cancel { + font-size: 1rem; + } + } + + &__footer-button { + width: 165px; + height: 60px; + font-size: 1rem; + text-transform: uppercase; + margin-right: 1rem; + border-radius: 2px; + + &:last-of-type { + margin-right: 0; + } + } + + &__title { + color: $black; + font-family: Roboto; + font-size: 2rem; + font-weight: 500; + line-height: initial; + } + + &__subtitle { + padding-top: .5rem; + line-height: initial; + font-size: .9rem; + color: $gray; + } + + &__tabs { + padding: 0 1.3rem; + display: flex; + } + + &__tab { + min-width: 5rem; + padding: .2rem .8rem .9rem; + color: $dusty-gray; + font-family: Roboto; + font-size: 1.1rem; + line-height: initial; + text-align: center; + cursor: pointer; + border-bottom: none; + margin-right: 1rem; + + &:hover { + color: $black; + } + + &:last-of-type { + margin-right: 0; + } + + &--selected { + color: $curious-blue; + border-bottom: 3px solid $curious-blue; + + &:hover { + color: $curious-blue; + } + } + } +} + +@media screen and (max-width: 250px) { + .page-container { + &__footer { + flex-flow: column-reverse; + } + + &__footer-button { + width: 100%; + margin-bottom: 1rem; + margin-right: 0; + + &:first-of-type { + margin-bottom: 0; + } + } + } +} + +@media screen and (max-width: 575px) { + .page-container { + height: 100%; + width: 100%; + overflow-y: auto; + background-color: $white; + } +} diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js index 24b37a83d..a4ed137f9 100644 --- a/ui/app/keychains/hd/restore-vault.js +++ b/ui/app/keychains/hd/restore-vault.js @@ -107,6 +107,7 @@ RestoreVaultScreen.prototype.render = function () { } RestoreVaultScreen.prototype.showInitializeMenu = function () { + this.props.dispatch(actions.unMarkPasswordForgotten()) if (this.props.forgottenPassword) { this.props.dispatch(actions.backToUnlockView()) } else { @@ -149,6 +150,9 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () { this.warning = null this.props.dispatch(actions.displayWarning(this.warning)) this.props.dispatch(actions.createNewVaultAndRestore(password, seed)) + .then(() => { + this.props.dispatch(actions.unMarkPasswordForgotten()) + }) .catch((err) => { log.error(err.message) }) diff --git a/ui/app/main-container.js b/ui/app/main-container.js index 031f61e84..292abcc3d 100644 --- a/ui/app/main-container.js +++ b/ui/app/main-container.js @@ -2,7 +2,6 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits const AccountAndTransactionDetails = require('./account-and-transaction-details') -const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const Settings = require('./settings') const UnlockScreen = require('./unlock') @@ -28,13 +27,6 @@ MainContainer.prototype.render = function () { if (this.props.isUnlocked === false) { switch (this.props.currentViewName) { - case 'restoreVault': - log.debug('rendering restore vault screen') - contents = { - component: HDRestoreVaultScreen, - key: 'HDRestoreVaultScreen', - } - break case 'config': log.debug('rendering config screen from unlock screen.') return h(Settings, {key: 'config'}) diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 6885d029a..02f024f7c 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -59,6 +59,7 @@ function reduceApp (state, action) { // Used to display error text warning: null, buyView: {}, + isMouseUser: false, }, state.appState) switch (action.type) { @@ -658,6 +659,12 @@ function reduceApp (state, action) { data: action.value.data, }, }) + + case actions.SET_MOUSE_USER_STATE: + return extend(appState, { + isMouseUser: action.value, + }) + default: return appState } diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 294c29948..beeba948d 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -1,6 +1,7 @@ const extend = require('xtend') const actions = require('../actions') const MetamascaraPlatform = require('../../../app/scripts/platforms/window') +const environmentType = require('../../../app/scripts/lib/environment-type') const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums module.exports = reduceMetamask @@ -14,6 +15,7 @@ function reduceMetamask (state, action) { isUnlocked: false, isAccountMenuOpen: false, isMascara: window.platform instanceof MetamascaraPlatform, + isPopup: environmentType() === 'popup', rpcTarget: 'https://rawtestrpc.metamask.io/', identities: {}, unapprovedTxs: {}, diff --git a/ui/app/selectors.js b/ui/app/selectors.js index 38a96c48b..5d2635775 100644 --- a/ui/app/selectors.js +++ b/ui/app/selectors.js @@ -116,7 +116,7 @@ function transactionsSelector (state) { // console.log({txsToRender, selectedTokenAddress}) return selectedTokenAddress ? txsToRender - .filter(({ txParams: { to } }) => to === selectedTokenAddress) + .filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress) .sort((a, b) => b.time - a.time) : txsToRender .sort((a, b) => b.time - a.time) @@ -179,11 +179,11 @@ function autoAddToBetaUI (state) { (numberOfAccounts > autoAddAccountsThreshold) && (numberOfTokensAdded > autoAddTokensThreshold) const userIsNotInBeta = !state.metamask.featureFlags.betaUI - + return userIsNotInBeta && userPassesThreshold } function getCurrentViewContext (state) { const { currentView = {} } = state.appState - return currentView.context + return currentView.context }
\ No newline at end of file diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 897caf16e..1d67150e3 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -5,7 +5,6 @@ const h = require('react-hyperscript') const ethAbi = require('ethereumjs-abi') const ethUtil = require('ethereumjs-util') -const Identicon = require('./components/identicon') const FromDropdown = require('./components/send/from-dropdown') const ToAutoComplete = require('./components/send/to-autocomplete') const CurrencyDisplay = require('./components/send/currency-display') @@ -179,52 +178,22 @@ SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) { } } -SendTransactionScreen.prototype.renderHeaderIcon = function () { - const { selectedToken } = this.props - - return h('div.send-v2__send-header-icon-container', [ - selectedToken - ? h(Identicon, { - diameter: 40, - address: selectedToken.address, - }) - : h('img.send-v2__send-header-icon', { src: '../images/eth_logo.svg' }), - ]) -} - -SendTransactionScreen.prototype.renderTitle = function () { - const { selectedToken } = this.props - - return h('div.send-v2__title', [selectedToken ? 'Send Tokens' : 'Send Funds']) -} - -SendTransactionScreen.prototype.renderCopy = function () { - const { selectedToken } = this.props - - const tokenText = selectedToken ? 'tokens' : 'ETH' - - return h('div.send-v2__form-header-copy', [ - - h('div.send-v2__copy', `Only send ${tokenText} to an Ethereum address.`), - - h('div.send-v2__copy', 'Sending to a different crytpocurrency that is not Ethereum may result in permanent loss.'), - - ]) -} - SendTransactionScreen.prototype.renderHeader = function () { - return h('div', [ - h('div.send-v2__header', {}, [ + const { selectedToken, clearSend, goHome } = this.props + const tokenText = selectedToken ? 'tokens' : 'ETH' - this.renderHeaderIcon(), + return h('div.page-container__header', [ - h('div.send-v2__arrow-background', [ - h('i.fa.fa-lg.fa-arrow-circle-right.send-v2__send-arrow-icon'), - ]), + h('div.page-container__title', selectedToken ? 'Send Tokens' : 'Send ETH'), - h('div.send-v2__header-tip'), + h('div.page-container__subtitle', `Only send ${tokenText} to an Ethereum address.`), - ]), + h('div.page-container__header-close', { + onClick: () => { + clearSend() + goHome() + }, + }), ]) } @@ -504,14 +473,6 @@ SendTransactionScreen.prototype.renderMemoRow = function () { SendTransactionScreen.prototype.renderForm = function () { return h('div.send-v2__form', {}, [ - h('div.sendV2__form-header', [ - - this.renderTitle(), - - this.renderCopy(), - - ]), - this.renderFromRow(), this.renderToRow(), @@ -535,14 +496,14 @@ SendTransactionScreen.prototype.renderFooter = function () { const noErrors = !amountError && toError === null - return h('div.send-v2__footer', [ - h('button.btn-cancel.send-v2__cancel-btn', { + return h('div.page-container__footer', [ + h('button.btn-cancel.page-container__footer-button', { onClick: () => { clearSend() goHome() }, }, 'Cancel'), - h('button.btn-clear.send-v2__next-btn', { + h('button.btn-clear.page-container__footer-button', { disabled: !noErrors || !gasTotal, onClick: event => this.onSubmit(event), }, 'Next'), @@ -552,7 +513,7 @@ SendTransactionScreen.prototype.renderFooter = function () { SendTransactionScreen.prototype.render = function () { return ( - h('div.send-v2__container', [ + h('div.page-container', [ this.renderHeader(), diff --git a/ui/app/settings.js b/ui/app/settings.js index 476bad296..988ddea8d 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -250,6 +250,24 @@ class Settings extends Component { ) } + renderResetAccount () { + const { showResetAccountConfirmationModal } = this.props + + return h('div.settings__content-row', [ + h('div.settings__content-item', 'Reset Account'), + h('div.settings__content-item', [ + h('div.settings__content-item-col', [ + h('button.settings__clear-button.settings__clear-button--orange', { + onClick (event) { + event.preventDefault() + showResetAccountConfirmationModal() + }, + }, 'Reset Account'), + ]), + ]), + ]) + } + renderSettingsContent () { const { warning, isMascara } = this.props @@ -262,6 +280,7 @@ class Settings extends Component { this.renderStateLogs(), this.renderSeedWords(), !isMascara && this.renderOldUI(), + this.renderResetAccount(), this.renderBlockieOptIn(), ]) ) @@ -387,6 +406,7 @@ Settings.propTypes = { displayWarning: PropTypes.func, revealSeedConfirmation: PropTypes.func, setFeatureFlagToBeta: PropTypes.func, + showResetAccountConfirmationModal: PropTypes.func, warning: PropTypes.string, goHome: PropTypes.func, isMascara: PropTypes.bool, @@ -412,6 +432,9 @@ const mapDispatchToProps = dispatch => { return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) .then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))) }, + showResetAccountConfirmationModal: () => { + return dispatch(actions.showModal({ name: 'CONFIRM_RESET_ACCOUNT' })) + }, } } diff --git a/ui/app/unlock.js b/ui/app/unlock.js index ec97b03bf..13c3f1274 100644 --- a/ui/app/unlock.js +++ b/ui/app/unlock.js @@ -5,6 +5,8 @@ const connect = require('react-redux').connect const actions = require('./actions') const getCaretCoordinates = require('textarea-caret') const EventEmitter = require('events').EventEmitter +const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums +const environmentType = require('../../app/scripts/lib/environment-type') const Mascot = require('./components/mascot') @@ -74,7 +76,12 @@ UnlockScreen.prototype.render = function () { h('.flex-row.flex-center.flex-grow', [ h('p.pointer', { - onClick: () => this.props.dispatch(actions.forgotPassword()), + onClick: () => { + this.props.dispatch(actions.markPasswordForgotten()) + if (environmentType() === 'popup') { + global.platform.openExtensionInBrowser() + } + }, style: { fontSize: '0.8em', color: 'rgb(247, 134, 28)', @@ -82,6 +89,22 @@ UnlockScreen.prototype.render = function () { }, }, 'Restore from seed phrase'), ]), + + h('.flex-row.flex-center.flex-grow', [ + h('p.pointer', { + onClick: () => { + this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) + .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))) + }, + style: { + fontSize: '0.8em', + color: '#aeaeae', + textDecoration: 'underline', + marginTop: '32px', + }, + }, 'Use classic interface'), + ]), + ]) ) } |