aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorDan <danjm.com@gmail.com>2018-03-07 08:15:45 +0800
committerDan <danjm.com@gmail.com>2018-03-07 08:15:45 +0800
commit9d215bab0fe124f036d2ac41f375331c8d43b72b (patch)
tree6bbbdb2e6a2dcd5948ee8473cad152232c73643b /ui
parentf06bca1151b07d908cd90f6efd97064e288e5f27 (diff)
parent9762a730413129361062804aa8dfc7be7cf74868 (diff)
downloadtangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.tar
tangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.tar.gz
tangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.tar.bz2
tangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.tar.lz
tangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.tar.xz
tangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.tar.zst
tangerine-wallet-browser-9d215bab0fe124f036d2ac41f375331c8d43b72b.zip
Merge branch 'master' into i18n
Diffstat (limited to 'ui')
-rw-r--r--ui/app/account-and-transaction-details.js7
-rw-r--r--ui/app/accounts/import/index.js2
-rw-r--r--ui/app/accounts/import/json.js6
-rw-r--r--ui/app/accounts/import/private-key.js19
-rw-r--r--ui/app/accounts/new-account/create-form.js13
-rw-r--r--ui/app/actions.js61
-rw-r--r--ui/app/add-token.js28
-rw-r--r--ui/app/app.js77
-rw-r--r--ui/app/components/account-dropdowns.js4
-rw-r--r--ui/app/components/account-menu/index.js11
-rw-r--r--ui/app/components/dropdowns/components/account-dropdowns.js4
-rw-r--r--ui/app/components/dropdowns/components/dropdown.js2
-rw-r--r--ui/app/components/dropdowns/network-dropdown.js40
-rw-r--r--ui/app/components/dropdowns/simple-dropdown.js2
-rw-r--r--ui/app/components/eth-balance.js2
-rw-r--r--ui/app/components/loading.js2
-rw-r--r--ui/app/components/modals/deposit-ether-modal.js5
-rw-r--r--ui/app/components/modals/modal.js25
-rw-r--r--ui/app/components/modals/notification-modal.js36
-rw-r--r--ui/app/components/modals/notification-modals/confirm-reset-account.js46
-rw-r--r--ui/app/components/notice.js3
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js16
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js14
-rw-r--r--ui/app/components/shapeshift-form.js19
-rw-r--r--ui/app/components/shift-list-item.js57
-rw-r--r--ui/app/components/tab-bar.js2
-rw-r--r--ui/app/components/token-cell.js26
-rw-r--r--ui/app/components/tooltip-v2.js31
-rw-r--r--ui/app/components/transaction-list-item.js2
-rw-r--r--ui/app/components/tx-list-item.js2
-rw-r--r--ui/app/components/tx-list.js7
-rw-r--r--ui/app/components/wallet-view.js36
-rw-r--r--ui/app/conf-tx.js1
-rw-r--r--ui/app/css/itcss/base/index.scss6
-rw-r--r--ui/app/css/itcss/components/account-menu.scss2
-rw-r--r--ui/app/css/itcss/components/confirm.scss14
-rw-r--r--ui/app/css/itcss/components/currency-display.scss3
-rw-r--r--ui/app/css/itcss/components/header.scss14
-rw-r--r--ui/app/css/itcss/components/hero-balance.scss24
-rw-r--r--ui/app/css/itcss/components/index.scss2
-rw-r--r--ui/app/css/itcss/components/modal.scss78
-rw-r--r--ui/app/css/itcss/components/network.scss5
-rw-r--r--ui/app/css/itcss/components/new-account.scss25
-rw-r--r--ui/app/css/itcss/components/newui-sections.scss49
-rw-r--r--ui/app/css/itcss/components/send.scss23
-rw-r--r--ui/app/css/itcss/components/token-list.scss21
-rw-r--r--ui/app/css/itcss/components/tooltip.scss7
-rw-r--r--ui/app/css/itcss/generic/index.scss133
-rw-r--r--ui/app/css/itcss/settings/typography.scss338
-rw-r--r--ui/app/first-time/init-menu.js24
-rw-r--r--ui/app/keychains/hd/restore-vault.js4
-rw-r--r--ui/app/main-container.js8
-rw-r--r--ui/app/reducers/app.js16
-rw-r--r--ui/app/reducers/metamask.js9
-rw-r--r--ui/app/selectors.js6
-rw-r--r--ui/app/send-v2.js84
-rw-r--r--ui/app/settings.js33
-rw-r--r--ui/app/unlock.js25
-rw-r--r--ui/index.js1
59 files changed, 1265 insertions, 297 deletions
diff --git a/ui/app/account-and-transaction-details.js b/ui/app/account-and-transaction-details.js
index 60293de77..03101d37a 100644
--- a/ui/app/account-and-transaction-details.js
+++ b/ui/app/account-and-transaction-details.js
@@ -13,12 +13,7 @@ function AccountAndTransactionDetails () {
}
AccountAndTransactionDetails.prototype.render = function () {
- return h('div', {
- style: {
- display: 'flex',
- flex: '1 0 auto',
- },
- }, [
+ return h('div.account-and-transaction-details', [
// wallet
h(WalletView, {
style: {
diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js
index 6ae74864f..ac6517424 100644
--- a/ui/app/accounts/import/index.js
+++ b/ui/app/accounts/import/index.js
@@ -38,7 +38,7 @@ AccountImportSubview.prototype.render = function () {
h('div.new-account-import-form__select-section', [
- h('div.new-account-import-form__select-label', 'SELECT TYPE'),
+ h('div.new-account-import-form__select-label', 'Select Type'),
h(Select, {
className: 'new-account-import-form__select',
diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js
index eb63a98a9..791759666 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/accounts/import/json.js
@@ -82,6 +82,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/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js
index e8c192a61..0b49d3281 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/accounts/import/private-key.js
@@ -33,15 +33,22 @@ PrivateKeyImportView.prototype.render = function () {
return (
h('div.new-account-import-form__private-key', [
+
h('span.new-account-create-form__instruction', t('pastePrivateKey')),
- h('input.new-account-import-form__input-password', {
- type: 'password',
- id: 'private-key-box',
- onKeyPress: () => this.createKeyringOnEnter(),
- }),
+ h('div.new-account-import-form__private-key-password-container', [
+
+ h('span.new-account-import-form__instruction', 'Paste your private key string here:'),
+
+ h('input.new-account-import-form__input-password', {
+ type: 'password',
+ id: 'private-key-box',
+ onKeyPress: () => this.createKeyringOnEnter(),
+ }),
+
+ ]),
- h('div.new-account-create-form__buttons', {}, [
+ h('div.new-account-import-form__buttons', {}, [
h('button.new-account-create-form__button-cancel.allcaps', {
onClick: () => goHome(),
diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/accounts/new-account/create-form.js
index ce8af394a..eb34f7a2f 100644
--- a/ui/app/accounts/new-account/create-form.js
+++ b/ui/app/accounts/new-account/create-form.js
@@ -8,16 +8,19 @@ const t = require('../../../i18n')
class NewAccountCreateForm extends Component {
constructor (props) {
super(props)
+
const { numberOfExistingAccounts = 0 } = props
const newAccountNumber = numberOfExistingAccounts + 1
this.state = {
- newAccountName: `Account ${newAccountNumber}`,
+ newAccountName: '',
+ defaultAccountName: t('newAccountNumberName', newAccountNumber),
}
}
render () {
- const { newAccountName } = this.state
+ const { newAccountName, defaultAccountName } = this.state
+
return h('div.new-account-create-form', [
@@ -27,8 +30,8 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__input-wrapper', {}, [
h('input.new-account-create-form__input', {
- value: this.state.newAccountName,
- placeholder: t('sampleAccountName'),
+ value: newAccountName,
+ placeholder: defaultAccountName,
onChange: event => this.setState({ newAccountName: event.target.value }),
}, []),
]),
@@ -42,7 +45,7 @@ class NewAccountCreateForm extends Component {
]),
h('button.new-account-create-form__button-create.allcaps', {
- onClick: () => this.props.createAccount(newAccountName),
+ onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
}, [
t('create'),
]),
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 25cb2c23f..8b1480a79 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',
@@ -55,6 +57,7 @@ var actions = {
SET_NEW_ACCOUNT_FORM: 'SET_NEW_ACCOUNT_FORM',
unlockMetamask: unlockMetamask,
unlockFailed: unlockFailed,
+ unlockSucceeded,
showCreateVault: showCreateVault,
showRestoreVault: showRestoreVault,
showInitializeMenu: showInitializeMenu,
@@ -69,15 +72,18 @@ 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',
+ UNLOCK_SUCCEEDED: 'UNLOCK_SUCCEEDED',
UNLOCK_METAMASK: 'UNLOCK_METAMASK',
LOCK_METAMASK: 'LOCK_METAMASK',
tryUnlockMetamask: tryUnlockMetamask,
@@ -251,6 +257,9 @@ var actions = {
updateFeatureFlags,
UPDATE_FEATURE_FLAGS: 'UPDATE_FEATURE_FLAGS',
+ setMouseUserState,
+ SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE',
+
// Network
setNetworkEndpoints,
updateNetworkEndpointType,
@@ -284,6 +293,7 @@ function tryUnlockMetamask (password) {
if (err) {
dispatch(actions.unlockFailed(err.message))
} else {
+ dispatch(actions.unlockSucceeded())
dispatch(actions.transitionForward())
forceUpdateMetamaskState(dispatch)
}
@@ -396,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())
@@ -816,9 +840,29 @@ function showRestoreVault () {
}
}
-function forgotPassword () {
+function markPasswordForgotten () {
+ return (dispatch) => {
+ return background.markPasswordForgotten(() => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.forgotPassword())
+ forceUpdateMetamaskState(dispatch)
+ })
+ }
+}
+
+function unMarkPasswordForgotten () {
+ return (dispatch) => {
+ return background.unMarkPasswordForgotten(() => {
+ dispatch(actions.forgotPassword(false))
+ forceUpdateMetamaskState(dispatch)
+ })
+ }
+}
+
+function forgotPassword (forgotPasswordState = true) {
return {
type: actions.FORGOT_PASSWORD,
+ value: forgotPasswordState,
}
}
@@ -890,6 +934,13 @@ function unlockFailed (message) {
}
}
+function unlockSucceeded (message) {
+ return {
+ type: actions.UNLOCK_SUCCEEDED,
+ value: message,
+ }
+}
+
function unlockMetamask (account) {
return {
type: actions.UNLOCK_METAMASK,
@@ -1447,6 +1498,7 @@ function pairUpdate (coin) {
dispatch(actions.hideWarning())
shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => {
dispatch(actions.hideSubLoadingIndication())
+ if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error))
dispatch({
type: actions.PAIR_UPDATE,
value: {
@@ -1611,6 +1663,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/add-token.js b/ui/app/add-token.js
index 3a806d34b..51c577987 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -52,13 +52,16 @@ function AddTokenScreen () {
isShowingConfirmation: false,
customAddress: '',
customSymbol: '',
- customDecimals: 0,
+ customDecimals: '',
searchQuery: '',
isCollapsed: true,
selectedTokens: {},
errors: {},
+ autoFilled: false,
}
this.tokenAddressDidChange = this.tokenAddressDidChange.bind(this)
+ this.tokenSymbolDidChange = this.tokenSymbolDidChange.bind(this)
+ this.tokenDecimalsDidChange = this.tokenDecimalsDidChange.bind(this)
this.onNext = this.onNext.bind(this)
Component.call(this)
}
@@ -103,6 +106,16 @@ AddTokenScreen.prototype.tokenAddressDidChange = function (e) {
}
}
+AddTokenScreen.prototype.tokenSymbolDidChange = function (e) {
+ const customSymbol = e.target.value.trim()
+ this.setState({ customSymbol })
+}
+
+AddTokenScreen.prototype.tokenDecimalsDidChange = function (e) {
+ const customDecimals = e.target.value.trim()
+ this.setState({ customDecimals })
+}
+
AddTokenScreen.prototype.checkExistingAddresses = function (address) {
if (!address) return false
const tokensList = this.props.tokens
@@ -125,7 +138,7 @@ AddTokenScreen.prototype.validate = function () {
errors.customAddress = 'Address is invalid. '
}
- const validDecimals = customDecimals >= 0 && customDecimals < 36
+ const validDecimals = customDecimals !== null && customDecimals >= 0 && customDecimals < 36
if (!validDecimals) {
errors.customDecimals = 'Decimals must be at least 0, and not over 36.'
}
@@ -166,12 +179,13 @@ AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address)
this.setState({
customSymbol: symbol,
customDecimals: decimals.toString(),
+ autoFilled: true,
})
}
}
AddTokenScreen.prototype.renderCustomForm = function () {
- const { customAddress, customSymbol, customDecimals, errors } = this.state
+ const { autoFilled, customAddress, customSymbol, customDecimals, errors } = this.state
return !this.state.isCollapsed && (
h('div.add-token__add-custom-form', [
@@ -196,8 +210,9 @@ AddTokenScreen.prototype.renderCustomForm = function () {
h('div.add-token__add-custom-label', 'Token Symbol'),
h('input.add-token__add-custom-input', {
type: 'text',
+ onChange: this.tokenSymbolDidChange,
value: customSymbol,
- disabled: true,
+ disabled: autoFilled,
}),
h('div.add-token__add-custom-error-message', errors.customSymbol),
]),
@@ -209,8 +224,9 @@ AddTokenScreen.prototype.renderCustomForm = function () {
h('div.add-token__add-custom-label', 'Decimals of Precision'),
h('input.add-token__add-custom-input', {
type: 'number',
+ onChange: this.tokenDecimalsDidChange,
value: customDecimals,
- disabled: true,
+ disabled: autoFilled,
}),
h('div.add-token__add-custom-error-message', errors.customDecimals),
]),
@@ -240,7 +256,7 @@ AddTokenScreen.prototype.renderTokenList = function () {
}, [
h('div.add-token__token-icon', {
style: {
- backgroundImage: `url(images/contract/${logo})`,
+ backgroundImage: logo && `url(images/contract/${logo})`,
},
}),
h('div.add-token__token-data', [
diff --git a/ui/app/app.js b/ui/app/app.js
index 3205baebb..8511ee396 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -10,7 +10,8 @@ const t = require('../i18n')
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 OldUIInitializeMenuScreen = require('./first-time/init-menu')
+const InitializeMenuScreen = MascaraFirstTime
const NewKeyChainScreen = require('./new-keychain')
// accounts
const MainContainer = require('./main-container')
@@ -75,17 +76,22 @@ 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,
+ isRevealingSeedWords: state.metamask.isRevealingSeedWords,
+ Qr: state.appState.Qr,
// state needed to get account dropdown temporarily rendering from app bar
identities,
@@ -102,6 +108,7 @@ function mapDispatchToProps (dispatch, ownProps) {
hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
+ setMouseUserState: (isMouseUser) => dispatch(actions.setMouseUserState(isMouseUser)),
}
}
@@ -113,7 +120,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
@@ -121,11 +134,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
@@ -221,6 +242,9 @@ App.prototype.renderAppBar = function () {
showNetworkDropdown,
hideNetworkDropdown,
currentView,
+ isInitialized,
+ betaUI,
+ isPopup,
} = this.props
if (window.METAMASK_UI_TYPE === 'notification') {
@@ -265,8 +289,10 @@ App.prototype.renderAppBar = function () {
}),
// metamask name
- h('h1', t('appName')),
-
+ h('.flex-row', [
+ h('h1', t('appName')),
+ h('div.beta-label', t('beta')),
+ ]),
]),
h('div.header__right-actions', [
@@ -299,6 +325,9 @@ App.prototype.renderAppBar = function () {
]),
]),
+ !isInitialized && !isPopup && betaUI && h('h2.alpha-warning',
+ 'Please be aware that this version is still under development'),
+
])
)
}
@@ -336,9 +365,17 @@ App.prototype.renderBackButton = function (style, justArrow = false) {
App.prototype.renderPrimary = function () {
log.debug('rendering primary')
var props = this.props
- const {isMascara, isOnboarding} = props
-
- if (isMascara && isOnboarding) {
+ const {
+ isMascara,
+ isOnboarding,
+ betaUI,
+ isRevealingSeedWords,
+ Qr,
+ } = props
+ const isMascaraOnboarding = isMascara && isOnboarding
+ const isBetaUIOnboarding = betaUI && isOnboarding && !props.isPopup && !isRevealingSeedWords
+
+ if (isMascaraOnboarding || isBetaUIOnboarding) {
return h(MascaraFirstTime)
}
@@ -359,20 +396,14 @@ 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 && !props.isUnlocked && !isRevealingSeedWords) {
+ log.debug('rendering menu screen')
+ return props.isPopup
+ ? h(OldUIInitializeMenuScreen, {key: 'menuScreenInit'})
+ : h(InitializeMenuScreen, {key: 'menuScreenInit'})
}
// show unlock screen
@@ -480,7 +511,7 @@ App.prototype.renderPrimary = function () {
width: '285px',
},
}, [
- h(QrView, {key: 'qr'}),
+ h(QrView, {key: 'qr', Qr}),
]),
])
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index e92da8947..1612d7b6a 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -1,5 +1,5 @@
const Component = require('react').Component
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const actions = require('../actions')
const genAccountLink = require('etherscan-link').createAccountLink
@@ -174,7 +174,7 @@ class AccountDropdowns extends Component {
minWidth: '180px',
},
isOpen: optionsMenuActive,
- onClickOutside: () => {
+ onClickOutside: (event) => {
const { classList } = event.target
const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
if (optionsMenuActive && isNotToggleElement) {
diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js
index d9cf8cdce..043e3d8d1 100644
--- a/ui/app/components/account-menu/index.js
+++ b/ui/app/components/account-menu/index.js
@@ -81,12 +81,12 @@ 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: t('createAccount'),
}),
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: t('importAccount'),
}),
h(Divider),
@@ -99,6 +99,13 @@ AccountMenu.prototype.render = function () {
onClick: showConfigPage,
icon: h('img', { src: 'images/settings.svg' }),
text: t('settings'),
+ icon: h('img.account-menu__item-icon', { src: 'images/mm-info-icon.svg' }),
+ text: t('infoHelp'),
+ }),
+ h(Item, {
+ onClick: showConfigPage,
+ icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }),
+ text: t('settings'),
}),
])
}
diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js
index 620ac8483..af29a4792 100644
--- a/ui/app/components/dropdowns/components/account-dropdowns.js
+++ b/ui/app/components/dropdowns/components/account-dropdowns.js
@@ -1,5 +1,5 @@
const Component = require('react').Component
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const actions = require('../../../actions')
const genAccountLink = require('../../../../lib/account-link.js')
@@ -282,7 +282,7 @@ class AccountDropdowns extends Component {
dropdownWrapperStyle,
),
isOpen: optionsMenuActive,
- onClickOutside: () => {
+ onClickOutside: (event) => {
const { classList } = event.target
const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
if (optionsMenuActive && isNotToggleElement) {
diff --git a/ui/app/components/dropdowns/components/dropdown.js b/ui/app/components/dropdowns/components/dropdown.js
index 15d064be8..0336dbb8b 100644
--- a/ui/app/components/dropdowns/components/dropdown.js
+++ b/ui/app/components/dropdowns/components/dropdown.js
@@ -1,5 +1,5 @@
const Component = require('react').Component
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const MenuDroppo = require('../../menu-droppo')
const extend = require('xtend')
diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js
index 0e16048d5..67daaa5fd 100644
--- a/ui/app/components/dropdowns/network-dropdown.js
+++ b/ui/app/components/dropdowns/network-dropdown.js
@@ -85,7 +85,7 @@ NetworkDropdown.prototype.render = function () {
style: {
position: 'absolute',
top: '58px',
- minWidth: '309px',
+ width: '309px',
zIndex: '55px',
},
innerStyle: {
@@ -277,11 +277,21 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
key: `common${rpc}`,
closeMenu: () => this.props.hideNetworkDropdown(),
onClick: () => props.setRpcTarget(rpc),
+ style: {
+ fontFamily: 'DIN OT',
+ fontSize: '16px',
+ lineHeight: '20px',
+ padding: '12px 0',
+ },
},
[
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- rpc,
- rpcTarget === rpc ? h('.check', '✓') : null,
+ rpcTarget === rpc ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h('i.fa.fa-question-circle.fa-med.menu-icon-circle'),
+ h('span.network-name-item', {
+ style: {
+ color: rpcTarget === rpc ? '#ffffff' : '#9b9b9b',
+ },
+ }, rpc),
]
)
}
@@ -294,12 +304,6 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) {
if (type !== 'rpc') return null
- // Concatenate long URLs
- let label = rpcTarget
- if (rpcTarget.length > 31) {
- label = label.substr(0, 34) + '...'
- }
-
switch (rpcTarget) {
case 'http://localhost:8545':
@@ -312,11 +316,21 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) {
key: rpcTarget,
onClick: () => props.setRpcTarget(rpcTarget),
closeMenu: () => this.props.hideNetworkDropdown(),
+ style: {
+ fontFamily: 'DIN OT',
+ fontSize: '16px',
+ lineHeight: '20px',
+ padding: '12px 0',
+ },
},
[
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- label,
- h('.check', '✓'),
+ h('i.fa.fa-check'),
+ h('i.fa.fa-question-circle.fa-med.menu-icon-circle'),
+ h('span.network-name-item', {
+ style: {
+ color: '#ffffff',
+ },
+ }, rpcTarget),
]
)
}
diff --git a/ui/app/components/dropdowns/simple-dropdown.js b/ui/app/components/dropdowns/simple-dropdown.js
index 7bb48e57b..bba088ed1 100644
--- a/ui/app/components/dropdowns/simple-dropdown.js
+++ b/ui/app/components/dropdowns/simple-dropdown.js
@@ -1,5 +1,5 @@
const { Component } = require('react')
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const classnames = require('classnames')
const R = require('ramda')
diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js
index 1be8c9731..c3d084bdc 100644
--- a/ui/app/components/eth-balance.js
+++ b/ui/app/components/eth-balance.js
@@ -46,7 +46,7 @@ EthBalanceComponent.prototype.renderBalance = function (value) {
incoming,
currentCurrency,
hideTooltip,
- styleOveride,
+ styleOveride = {},
showFiat = true,
} = this.props
const { fontSize, color, fontFamily, lineHeight } = styleOveride
diff --git a/ui/app/components/loading.js b/ui/app/components/loading.js
index 9442121fe..cb6fa51fb 100644
--- a/ui/app/components/loading.js
+++ b/ui/app/components/loading.js
@@ -1,6 +1,6 @@
const { Component } = require('react')
const h = require('react-hyperscript')
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
class LoadingIndicator extends Component {
renderMessage () {
diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js
index 7172d05a5..6c593e4e5 100644
--- a/ui/app/components/modals/deposit-ether-modal.js
+++ b/ui/app/components/modals/deposit-ether-modal.js
@@ -33,6 +33,9 @@ function mapDispatchToProps (dispatch) {
hideModal: () => {
dispatch(actions.hideModal())
},
+ hideWarning: () => {
+ dispatch(actions.hideWarning())
+ },
showAccountDetailModal: () => {
dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
},
@@ -119,6 +122,7 @@ DepositEtherModal.prototype.render = function () {
h('div.deposit-ether-modal__header__close', {
onClick: () => {
this.setState({ buyingWithShapeshift: false })
+ this.props.hideWarning()
this.props.hideModal()
},
}),
@@ -179,6 +183,7 @@ DepositEtherModal.prototype.render = function () {
}
DepositEtherModal.prototype.goToAccountDetailsModal = function () {
+ this.props.hideWarning()
this.props.hideModal()
this.props.showAccountDetailModal()
}
diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js
index ea6ac5135..7d4089ab3 100644
--- a/ui/app/components/modals/modal.js
+++ b/ui/app/components/modals/modal.js
@@ -19,6 +19,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: {
@@ -79,6 +80,7 @@ const MODALS = {
contents: [
h(DepositEtherModal, {}, []),
],
+ onHide: (props) => props.hideWarning(),
mobileModalStyle: {
width: '100%',
height: '100%',
@@ -201,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, {}, []),
@@ -272,6 +286,10 @@ function mapDispatchToProps (dispatch) {
hideModal: () => {
dispatch(actions.hideModal())
},
+ hideWarning: () => {
+ dispatch(actions.hideWarning())
+ },
+
}
}
@@ -294,7 +312,12 @@ Modal.prototype.render = function () {
{
className: 'modal',
keyboard: false,
- onHide: () => { this.onHide() },
+ onHide: () => {
+ if (modal.onHide) {
+ modal.onHide(this.props)
+ }
+ this.onHide()
+ },
ref: (ref) => {
this.modalRef = ref
},
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/notice.js b/ui/app/components/notice.js
index 390639297..8b0ce1e8b 100644
--- a/ui/app/components/notice.js
+++ b/ui/app/components/notice.js
@@ -106,8 +106,7 @@ Notice.prototype.render = function () {
h('button.primary', {
disabled,
onClick: () => {
- this.setState({disclaimerDisabled: true})
- onConfirm()
+ this.setState({disclaimerDisabled: true}, () => onConfirm())
},
style: {
marginTop: '18px',
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index 21b9b548b..4d4732bdb 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -214,17 +214,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 b1bec946a..606aca3c2 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -309,17 +309,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.allcaps', {
+ h('div.page-container', [
+ h('div.page-container__header', [
+ h('button.confirm-screen-back-button', {
onClick: () => editTransaction(txMeta),
}, t('edit')),
- h('div.confirm-screen-title', t('confirmTransaction')),
- h('div.confirm-screen-header-tip'),
+ h('div.page-container__title', t('confirm')),
+ h('div.page-container__subtitle', t('pleaseReviewTransaction')),
]),
h('div.flex-row.flex-center.confirm-screen-identicons', [
h('div.confirm-screen-account-wrapper', [
diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index 104f82224..f75d6176e 100644
--- a/ui/app/components/shapeshift-form.js
+++ b/ui/app/components/shapeshift-form.js
@@ -15,11 +15,13 @@ function mapStateToProps (state) {
tokenExchangeRates,
selectedAddress,
} = state.metamask
+ const { warning } = state.appState
return {
coinOptions,
tokenExchangeRates,
selectedAddress,
+ warning,
}
}
@@ -52,8 +54,7 @@ ShapeshiftForm.prototype.componentWillMount = function () {
this.props.shapeShiftSubview()
}
-ShapeshiftForm.prototype.onCoinChange = function (e) {
- const coin = e.target.value
+ShapeshiftForm.prototype.onCoinChange = function (coin) {
this.setState({
depositCoin: coin,
errorMessage: '',
@@ -134,7 +135,7 @@ ShapeshiftForm.prototype.renderMarketInfo = function () {
}
ShapeshiftForm.prototype.renderQrCode = function () {
- const { depositAddress, isLoading } = this.state
+ const { depositAddress, isLoading, depositCoin } = this.state
const qrImage = qrcode(4, 'M')
qrImage.addData(depositAddress)
qrImage.make()
@@ -142,7 +143,7 @@ ShapeshiftForm.prototype.renderQrCode = function () {
return h('div.shapeshift-form', {}, [
h('div.shapeshift-form__deposit-instruction', [
- t('depositBTC'),
+ t('depositCoin', depositCoin.toUpperCase()),
]),
h('div', depositAddress),
@@ -165,7 +166,7 @@ ShapeshiftForm.prototype.renderQrCode = function () {
ShapeshiftForm.prototype.render = function () {
- const { coinOptions, btnClass } = this.props
+ const { coinOptions, btnClass, warning } = this.props
const { depositCoin, errorMessage, showQrCode, depositAddress } = this.state
const coinPair = `${depositCoin}_eth`
const { tokenExchangeRates } = this.props
@@ -183,7 +184,7 @@ ShapeshiftForm.prototype.render = function () {
h(SimpleDropdown, {
selectedOption: this.state.depositCoin,
- onSelect: this.onCoinChange,
+ onSelect: (coin) => this.onCoinChange(coin),
options: Object.entries(coinOptions).map(([coin]) => ({
value: coin.toLowerCase(),
displayValue: coin,
@@ -208,7 +209,9 @@ ShapeshiftForm.prototype.render = function () {
]),
- h('div', {
+ warning && h('div.shapeshift-form__address-input-label', warning),
+
+ !warning && h('div', {
className: classnames('shapeshift-form__address-input-wrapper', {
'shapeshift-form__address-input-wrapper--error': errorMessage,
}),
@@ -229,7 +232,7 @@ ShapeshiftForm.prototype.render = function () {
h('divshapeshift-form__address-input-error-message', [errorMessage]),
]),
- this.renderMarketInfo(),
+ !warning && this.renderMarketInfo(),
]),
diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js
index 0d8681fb7..fddbc6821 100644
--- a/ui/app/components/shift-list-item.js
+++ b/ui/app/components/shift-list-item.js
@@ -30,40 +30,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/tab-bar.js b/ui/app/components/tab-bar.js
index 0edced119..a80640116 100644
--- a/ui/app/components/tab-bar.js
+++ b/ui/app/components/tab-bar.js
@@ -1,6 +1,6 @@
const { Component } = require('react')
const h = require('react-hyperscript')
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const classnames = require('classnames')
class TabBar extends Component {
diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js
index 59552f4a0..0332fde88 100644
--- a/ui/app/components/token-cell.js
+++ b/ui/app/components/token-cell.js
@@ -111,20 +111,24 @@ TokenCell.prototype.render = function () {
network,
}),
- h('h.token-list-item__balance-wrapper', null, [
- h('h3.token-list-item__token-balance', `${string || 0} ${symbol}`),
+ 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}`),
+
+ showFiat && h('div.token-list-item__fiat-amount', {
+ style: {},
+ }, formattedFiat),
+ ]),
+
+ h('i.fa.fa-ellipsis-h.fa-lg.token-list-item__ellipsis.cursor-pointer', {
+ onClick: (e) => {
+ e.stopPropagation()
+ this.setState({ tokenMenuOpen: true })
+ },
+ }),
- showFiat && h('div.token-list-item__fiat-amount', {
- style: {},
- }, formattedFiat),
]),
- h('i.fa.fa-ellipsis-h.fa-lg.token-list-item__ellipsis.cursor-pointer', {
- onClick: (e) => {
- e.stopPropagation()
- this.setState({ tokenMenuOpen: true })
- },
- }),
tokenMenuOpen && h(TokenMenuDropdown, {
onClose: () => this.setState({ tokenMenuOpen: false }),
diff --git a/ui/app/components/tooltip-v2.js b/ui/app/components/tooltip-v2.js
new file mode 100644
index 000000000..133a0f16a
--- /dev/null
+++ b/ui/app/components/tooltip-v2.js
@@ -0,0 +1,31 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const ReactTippy = require('react-tippy').Tooltip
+
+module.exports = Tooltip
+
+inherits(Tooltip, Component)
+function Tooltip () {
+ Component.call(this)
+}
+
+Tooltip.prototype.render = function () {
+ const props = this.props
+ const { position, title, children, wrapperClassName } = props
+
+ return h('div', {
+ className: wrapperClassName,
+ }, [
+
+ h(ReactTippy, {
+ title,
+ position: position || 'left',
+ trigger: 'mouseenter',
+ hideOnClick: false,
+ size: 'small',
+ arrow: true,
+ }, children),
+
+ ])
+}
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index 6baf60141..6d6e79bd5 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -181,7 +181,7 @@ function recipientField (txParams, transaction, isTx, isMsg) {
} else if (txParams.to) {
message = addressSummary(txParams.to)
} else {
- message = t('contractPublished')
+ message = t('contractDeployment')
}
return h('div', {
diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js
index 7a38096b6..849d70489 100644
--- a/ui/app/components/tx-list-item.js
+++ b/ui/app/components/tx-list-item.js
@@ -64,7 +64,7 @@ TxListItem.prototype.getAddressText = function () {
default:
return address
? `${address.slice(0, 10)}...${address.slice(-4)}`
- : t('contractPublished')
+ : t('contractDeployment')
}
}
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
index 8343ec46b..34dc837ae 100644
--- a/ui/app/components/tx-list.js
+++ b/ui/app/components/tx-list.js
@@ -51,6 +51,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(
@@ -66,11 +67,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/components/wallet-view.js b/ui/app/components/wallet-view.js
index 6bd2d0963..18452205c 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -2,8 +2,10 @@ const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const inherits = require('util').inherits
+const classnames = require('classnames')
const Identicon = require('./identicon')
// const AccountDropdowns = require('./dropdowns/index.js').AccountDropdowns
+const Tooltip = require('./tooltip-v2.js')
const copyToClipboard = require('copy-to-clipboard')
const actions = require('../actions')
const BalanceComponent = require('./balance-component')
@@ -46,6 +48,7 @@ function WalletView () {
Component.call(this)
this.state = {
hasCopied: false,
+ copyToClipboardPressed: false,
}
}
@@ -135,17 +138,30 @@ WalletView.prototype.render = function () {
]),
]),
-
- h('div.wallet-view__address', {
- onClick: () => {
- copyToClipboard(selectedAddress)
- this.setState({ hasCopied: true })
- setTimeout(() => this.setState({ hasCopied: false }), 3000)
- },
+ h(Tooltip, {
+ position: 'bottom',
+ title: this.state.hasCopied ? t('copiedExclamation') : t('copyToClipboard'),
+ wrapperClassName: 'wallet-view__tooltip',
}, [
- this.state.hasCopied && t('copiedClipboard'),
- !this.state.hasCopied && `${selectedAddress.slice(0, 4)}...${selectedAddress.slice(-4)}`,
- h('i.fa.fa-clipboard', { style: { marginLeft: '8px' } }),
+ h('button.wallet-view__address', {
+ className: classnames({
+ 'wallet-view__address__pressed': this.state.copyToClipboardPressed,
+ }),
+ onClick: () => {
+ copyToClipboard(selectedAddress)
+ this.setState({ hasCopied: true })
+ setTimeout(() => this.setState({ hasCopied: false }), 3000)
+ },
+ onMouseDown: () => {
+ this.setState({ copyToClipboardPressed: true })
+ },
+ onMouseUp: () => {
+ this.setState({ copyToClipboardPressed: false })
+ },
+ }, [
+ `${selectedAddress.slice(0, 4)}...${selectedAddress.slice(-4)}`,
+ h('i.fa.fa-clipboard', { style: { marginLeft: '8px' } }),
+ ]),
]),
this.renderWalletBalance(),
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 9f273aaec..b4ffc48b7 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -108,7 +108,6 @@ ConfirmTxScreen.prototype.render = function () {
cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
cancelTypedMessage: this.cancelTypedMessage.bind(this, txData),
})
-
}
function currentTxView (opts) {
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/header.scss b/ui/app/css/itcss/components/header.scss
index ac2cecf7e..eeed9ee06 100644
--- a/ui/app/css/itcss/components/header.scss
+++ b/ui/app/css/itcss/components/header.scss
@@ -76,6 +76,20 @@
}
}
+.beta-label {
+ font-family: Roboto;
+ text-transform: uppercase;
+ font-weight: 500;
+ font-size: .8rem;
+ color: $buttercup;
+ margin-left: 5px;
+ line-height: initial;
+
+ @media screen and (max-width: 575px) {
+ display: none;
+ }
+}
+
h2.page-subtitle {
text-transform: uppercase;
color: #aeaeae;
diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss
index ccc9a0118..4af0c2c55 100644
--- a/ui/app/css/itcss/components/hero-balance.scss
+++ b/ui/app/css/itcss/components/hero-balance.scss
@@ -71,6 +71,22 @@
font-size: 105%;
}
}
+
+ @media #{$sub-mid-size-breakpoint-range} {
+ margin-left: .4em;
+ margin-right: .4em;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ .token-amount {
+ font-size: 1rem;
+ }
+
+ .fiat-amount {
+ margin-top: .25%;
+ font-size: 1rem;
+ }
+ }
}
.hero-balance-buttons {
@@ -91,4 +107,12 @@
.hero-balance-button {
width: 6rem;
+
+ @media #{$sub-mid-size-breakpoint-range} {
+ padding: 0.4rem;
+ width: 4rem;
+ display: flex;
+ flex: 1;
+ justify-content: center;
+ }
}
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
index d1b9b6277..0219f9fb2 100644
--- a/ui/app/css/itcss/components/index.scss
+++ b/ui/app/css/itcss/components/index.scss
@@ -53,3 +53,5 @@
@import './editable-label.scss';
@import './new-account.scss';
+
+@import './tooltip.scss';
diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss
index 5bca4a07d..53e3bff00 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
@@ -771,6 +787,10 @@
width: auto;
flex: 1;
}
+
+ @media screen and (max-width: 575px) {
+ width: auto;
+ }
}
}
diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss
index d9a39b8d5..c32d1de5e 100644
--- a/ui/app/css/itcss/components/network.scss
+++ b/ui/app/css/itcss/components/network.scss
@@ -76,8 +76,11 @@
.network-name-item {
font-weight: 100;
- flex: 1 0 auto;
+ flex: 1;
color: $dusty-gray;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
}
.network-check,
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
index c5e4ea761..81f919df3 100644
--- a/ui/app/css/itcss/components/new-account.scss
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -55,11 +55,17 @@
}
.new-account-import-form {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ padding: 0 30px;
+
&__select-section {
display: flex;
- justify-content: space-evenly;
+ justify-content: space-between;
align-items: center;
margin-top: 29px;
+ width: 100%;
}
&__select-label {
@@ -91,19 +97,25 @@
}
}
+ &__private-key-password-container {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ width: 100%;
+ }
+
&__instruction {
color: $scorpion;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
align-self: flex-start;
- margin-left: 30px;
}
&__private-key {
display: flex;
flex-flow: column;
- align-items: center;
+ align-items: flex-start;
margin-top: 34px;
}
@@ -126,6 +138,13 @@
align-items: center;
margin-top: 29px;
}
+
+ &__buttons {
+ margin-top: 39px;
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ }
}
.new-account-create-form {
diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss
index 1c26882b5..ecf5e1036 100644
--- a/ui/app/css/itcss/components/newui-sections.scss
+++ b/ui/app/css/itcss/components/newui-sections.scss
@@ -1,3 +1,6 @@
+$sub-mid-size-breakpoint: 667px;
+$sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (max-width: #{$sub-mid-size-breakpoint})";
+
/*
NewUI Container Elements
*/
@@ -20,6 +23,12 @@ $wallet-view-bg: $alabaster;
display: none;
}
+//Account and transaction details
+.account-and-transaction-details {
+ display: flex;
+ flex: 1 0 auto;
+}
+
// tx view
.tx-view {
@@ -60,6 +69,10 @@ $wallet-view-bg: $alabaster;
overflow-x: hidden;
}
+ @media #{$sub-mid-size-breakpoint-range} {
+ min-width: 160px;
+ }
+
.wallet-view-account-details {
flex: 0 0 auto;
}
@@ -89,6 +102,13 @@ $wallet-view-bg: $alabaster;
flex: 0 0 auto;
}
+ &__tooltip {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 24px;
+ }
+
&__address {
border-radius: 3px;
background-color: $alto;
@@ -96,10 +116,13 @@ $wallet-view-bg: $alabaster;
font-size: 14px;
line-height: 12px;
padding: 4px 12px;
- margin: 24px auto;
font-weight: 300;
cursor: pointer;
flex: 0 0 auto;
+
+ &__pressed {
+ background-color: $manatee,
+ }
}
&__sidebar-close {
@@ -267,3 +290,27 @@ $wallet-view-bg: $alabaster;
.token-balance__amount {
padding-right: 6px;
}
+
+
+// first time
+.first-view-main {
+ display: flex;
+ flex-direction: row-reverse;
+ justify-content: space-between;
+
+ @media screen and (max-width: 575px) {
+ height: 100%;
+ }
+
+ @media screen and (min-width: 576px) {
+ width: 85vw;
+ }
+
+ @media screen and (min-width: 769px) {
+ width: 80vw;
+ }
+
+ @media screen and (min-width: 1281px) {
+ width: 62vw;
+ }
+} \ No newline at end of file
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 e24bf812b..9dc4f1055 100644
--- a/ui/app/css/itcss/components/token-list.scss
+++ b/ui/app/css/itcss/components/token-list.scss
@@ -15,7 +15,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
font-size: 1.5rem;
@media #{$wallet-balance-breakpoint-range} {
- font-size: 105%;
+ font-size: 95%;
}
}
@@ -41,17 +41,22 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
&__identicon {
margin-right: 15px;
border: '1px solid #dedede';
+ min-width: 50px;
@media #{$wallet-balance-breakpoint-range} {
margin-right: 4%;
}
}
+ &__balance-ellipsis {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ }
+
&__ellipsis {
- // position: absolute;
- // top: 20px;
- // right: 24px;
line-height: 45px;
+ margin-left: 5px;
}
&__balance-wrapper {
@@ -61,7 +66,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
.token-menu-dropdown {
height: 55px;
- width: 191px;
+ width: 80%;
border-radius: 4px;
background-color: rgba(0, 0, 0, .82);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5);
@@ -70,6 +75,10 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
right: 25px;
z-index: 2000;
+ @media #{$wallet-balance-breakpoint-range} {
+ right: 18px;
+ }
+
&__close-area {
position: fixed;
top: 0;
@@ -81,7 +90,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (
}
&__container {
- padding: 16px 34px 32px;
+ padding: 16px;
z-index: 2200;
position: relative;
}
diff --git a/ui/app/css/itcss/components/tooltip.scss b/ui/app/css/itcss/components/tooltip.scss
new file mode 100644
index 000000000..78325865e
--- /dev/null
+++ b/ui/app/css/itcss/components/tooltip.scss
@@ -0,0 +1,7 @@
+.metamask-tooltip {
+ padding: 5px !important;
+}
+
+// needed for react-tippy
+// copied from node_modules/react-tippy/dist/tippy.css
+.tippy-touch{cursor:pointer!important}.tippy-notransition{transition:none!important}.tippy-popper{max-width:400px;-webkit-perspective:800px;perspective:800px;z-index:9999;outline:0;transition-timing-function:cubic-bezier(.165,.84,.44,1);pointer-events:none}.tippy-popper.html-template{max-width:96%;max-width:calc(100% - 20px)}.tippy-popper[x-placement^=top] [x-arrow]{border-top:7px solid #333;border-right:7px solid transparent;border-left:7px solid transparent;bottom:-7px;margin:0 9px}.tippy-popper[x-placement^=top] [x-arrow].arrow-small{border-top:5px solid #333;border-right:5px solid transparent;border-left:5px solid transparent;bottom:-5px}.tippy-popper[x-placement^=top] [x-arrow].arrow-big{border-top:10px solid #333;border-right:10px solid transparent;border-left:10px solid transparent;bottom:-10px}.tippy-popper[x-placement^=top] [x-circle]{-webkit-transform-origin:0 33%;transform-origin:0 33%}.tippy-popper[x-placement^=top] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-55%);transform:scale(1) translate(-50%,-55%);opacity:1}.tippy-popper[x-placement^=top] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-50%);transform:scale(.15) translate(-50%,-50%);opacity:0}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-arrow]{border-top:7px solid #fff;border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-top:5px solid #fff;border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-top:10px solid #fff;border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-arrow]{border-top:7px solid rgba(0,0,0,.7);border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-top:5px solid rgba(0,0,0,.7);border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-top:10px solid rgba(0,0,0,.7);border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=top] [data-animation=perspective]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateY(-10px) rotateX(0);transform:translateY(-10px) rotateX(0)}.tippy-popper[x-placement^=top] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateY(0) rotateX(90deg);transform:translateY(0) rotateX(90deg)}.tippy-popper[x-placement^=top] [data-animation=fade].enter{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=fade].leave{opacity:0;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift].enter{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift].leave{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=top] [data-animation=scale].enter{opacity:1;-webkit-transform:translateY(-10px) scale(1);transform:translateY(-10px) scale(1)}.tippy-popper[x-placement^=top] [data-animation=scale].leave{opacity:0;-webkit-transform:translateY(0) scale(0);transform:translateY(0) scale(0)}.tippy-popper[x-placement^=bottom] [x-arrow]{border-bottom:7px solid #333;border-right:7px solid transparent;border-left:7px solid transparent;top:-7px;margin:0 9px}.tippy-popper[x-placement^=bottom] [x-arrow].arrow-small{border-bottom:5px solid #333;border-right:5px solid transparent;border-left:5px solid transparent;top:-5px}.tippy-popper[x-placement^=bottom] [x-arrow].arrow-big{border-bottom:10px solid #333;border-right:10px solid transparent;border-left:10px solid transparent;top:-10px}.tippy-popper[x-placement^=bottom] [x-circle]{-webkit-transform-origin:0 -50%;transform-origin:0 -50%}.tippy-popper[x-placement^=bottom] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-45%);transform:scale(1) translate(-50%,-45%);opacity:1}.tippy-popper[x-placement^=bottom] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-5%);transform:scale(.15) translate(-50%,-5%);opacity:0}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-arrow]{border-bottom:7px solid #fff;border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-bottom:5px solid #fff;border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-bottom:10px solid #fff;border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-arrow]{border-bottom:7px solid rgba(0,0,0,.7);border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-bottom:5px solid rgba(0,0,0,.7);border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-bottom:10px solid rgba(0,0,0,.7);border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=bottom] [data-animation=perspective]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateY(10px) rotateX(0);transform:translateY(10px) rotateX(0)}.tippy-popper[x-placement^=bottom] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateY(0) rotateX(-90deg);transform:translateY(0) rotateX(-90deg)}.tippy-popper[x-placement^=bottom] [data-animation=fade].enter{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=fade].leave{opacity:0;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift].enter{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift].leave{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=bottom] [data-animation=scale].enter{opacity:1;-webkit-transform:translateY(10px) scale(1);transform:translateY(10px) scale(1)}.tippy-popper[x-placement^=bottom] [data-animation=scale].leave{opacity:0;-webkit-transform:translateY(0) scale(0);transform:translateY(0) scale(0)}.tippy-popper[x-placement^=left] [x-arrow]{border-left:7px solid #333;border-top:7px solid transparent;border-bottom:7px solid transparent;right:-7px;margin:6px 0}.tippy-popper[x-placement^=left] [x-arrow].arrow-small{border-left:5px solid #333;border-top:5px solid transparent;border-bottom:5px solid transparent;right:-5px}.tippy-popper[x-placement^=left] [x-arrow].arrow-big{border-left:10px solid #333;border-top:10px solid transparent;border-bottom:10px solid transparent;right:-10px}.tippy-popper[x-placement^=left] [x-circle]{-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=left] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-50%);transform:scale(1) translate(-50%,-50%);opacity:1}.tippy-popper[x-placement^=left] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-50%);transform:scale(.15) translate(-50%,-50%);opacity:0}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-arrow]{border-left:7px solid #fff;border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-left:5px solid #fff;border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-left:10px solid #fff;border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-arrow]{border-left:7px solid rgba(0,0,0,.7);border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-left:5px solid rgba(0,0,0,.7);border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-left:10px solid rgba(0,0,0,.7);border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=left] [data-animation=perspective]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateX(-10px) rotateY(0);transform:translateX(-10px) rotateY(0)}.tippy-popper[x-placement^=left] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateX(0) rotateY(-90deg);transform:translateX(0) rotateY(-90deg)}.tippy-popper[x-placement^=left] [data-animation=fade].enter{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=fade].leave{opacity:0;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift].enter{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift].leave{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=left] [data-animation=scale].enter{opacity:1;-webkit-transform:translateX(-10px) scale(1);transform:translateX(-10px) scale(1)}.tippy-popper[x-placement^=left] [data-animation=scale].leave{opacity:0;-webkit-transform:translateX(0) scale(0);transform:translateX(0) scale(0)}.tippy-popper[x-placement^=right] [x-arrow]{border-right:7px solid #333;border-top:7px solid transparent;border-bottom:7px solid transparent;left:-7px;margin:6px 0}.tippy-popper[x-placement^=right] [x-arrow].arrow-small{border-right:5px solid #333;border-top:5px solid transparent;border-bottom:5px solid transparent;left:-5px}.tippy-popper[x-placement^=right] [x-arrow].arrow-big{border-right:10px solid #333;border-top:10px solid transparent;border-bottom:10px solid transparent;left:-10px}.tippy-popper[x-placement^=right] [x-circle]{-webkit-transform-origin:-50% 0;transform-origin:-50% 0}.tippy-popper[x-placement^=right] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-50%);transform:scale(1) translate(-50%,-50%);opacity:1}.tippy-popper[x-placement^=right] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-50%);transform:scale(.15) translate(-50%,-50%);opacity:0}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-arrow]{border-right:7px solid #fff;border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-right:5px solid #fff;border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-right:10px solid #fff;border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-arrow]{border-right:7px solid rgba(0,0,0,.7);border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-right:5px solid rgba(0,0,0,.7);border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-right:10px solid rgba(0,0,0,.7);border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=right] [data-animation=perspective]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateX(10px) rotateY(0);transform:translateX(10px) rotateY(0)}.tippy-popper[x-placement^=right] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateX(0) rotateY(90deg);transform:translateX(0) rotateY(90deg)}.tippy-popper[x-placement^=right] [data-animation=fade].enter{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=fade].leave{opacity:0;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift].enter{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift].leave{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=right] [data-animation=scale].enter{opacity:1;-webkit-transform:translateX(10px) scale(1);transform:translateX(10px) scale(1)}.tippy-popper[x-placement^=right] [data-animation=scale].leave{opacity:0;-webkit-transform:translateX(0) scale(0);transform:translateX(0) scale(0)}.tippy-popper .tippy-tooltip.transparent-theme{background-color:rgba(0,0,0,.7)}.tippy-popper .tippy-tooltip.transparent-theme[data-animatefill]{background-color:transparent}.tippy-popper .tippy-tooltip.light-theme{color:#26323d;box-shadow:0 4px 20px 4px rgba(0,20,60,.1),0 4px 80px -8px rgba(0,20,60,.2);background-color:#fff}.tippy-popper .tippy-tooltip.light-theme[data-animatefill]{background-color:transparent}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:.95rem;padding:.4rem .8rem;text-align:center;will-change:transform;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#333}.tippy-tooltip--small{padding:.25rem .5rem;font-size:.8rem}.tippy-tooltip--big{padding:.6rem 1.2rem;font-size:1.2rem}.tippy-tooltip[data-animatefill]{overflow:hidden;background-color:transparent}.tippy-tooltip[data-interactive]{pointer-events:auto}.tippy-tooltip[data-inertia]{transition-timing-function:cubic-bezier(.53,2,.36,.85)}.tippy-tooltip [x-arrow]{position:absolute;width:0;height:0}.tippy-tooltip [x-circle]{position:absolute;will-change:transform;background-color:#333;border-radius:50%;width:130%;width:calc(110% + 2rem);left:50%;top:50%;z-index:-1;overflow:hidden;transition:all ease}.tippy-tooltip [x-circle]:before{content:"";padding-top:90%;float:left}@media (max-width:450px){.tippy-popper{max-width:96%;max-width:calc(100% - 20px)}}
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index 91c85f073..38c3b34fb 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -73,3 +73,136 @@ input.large-input {
.allcaps {
text-transform: uppercase;
}
+
+.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/css/itcss/settings/typography.scss b/ui/app/css/itcss/settings/typography.scss
index ac8c41336..8a56d9c6c 100644
--- a/ui/app/css/itcss/settings/typography.scss
+++ b/ui/app/css/itcss/settings/typography.scss
@@ -1,6 +1,340 @@
-@import url('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900');
+@import url('/fonts/Font_Awesome/font-awesome.min.css');
-@import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css');
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: local('Roboto Thin'), local('Roboto-Thin'), url('fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Roboto Light'), local('Roboto-Light'), url('fonts/Roboto/Roboto-Light.ttf') format('truetype');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'), url('fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Roboto Bold'), local('Roboto-Bold'), url('fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: local('Roboto Black'), local('Roboto-Black'), url('fonts/Roboto/Roboto-Black.ttf') format('truetype');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
@font-face {
font-family: 'Montserrat Regular';
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index 6b50bf504..370fdd5b7 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -8,6 +8,8 @@ const actions = require('../actions')
const Tooltip = require('../components/tooltip')
const t = require('../../i18n')
const getCaretCoordinates = require('textarea-caret')
+const environmentType = require('../../../app/scripts/lib/environment-type')
+const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums
let isSubmitting = false
@@ -131,6 +133,18 @@ InitializeMenuScreen.prototype.renderMenu = function (state) {
}, t('importDen')),
]),
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.showOldUI.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, 'Use classic interface'),
+ ]),
+
])
)
}
@@ -147,7 +161,15 @@ InitializeMenuScreen.prototype.componentDidMount = function () {
}
InitializeMenuScreen.prototype.showRestoreVault = function () {
- this.props.dispatch(actions.showRestoreVault())
+ this.props.dispatch(actions.markPasswordForgotten())
+ if (environmentType() === 'popup') {
+ global.platform.openExtensionInBrowser()
+ }
+}
+
+InitializeMenuScreen.prototype.showOldUI = function () {
+ this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
+ .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
}
InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
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 c3ade5cdc..4dda839a2 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) {
@@ -139,10 +140,10 @@ function reduceApp (state, action) {
case actions.FORGOT_PASSWORD:
return extend(appState, {
currentView: {
- name: 'restoreVault',
+ name: action.value ? 'restoreVault' : 'accountDetail',
},
transForward: false,
- forgottenPassword: true,
+ forgottenPassword: action.value,
})
case actions.SHOW_INIT_MENU:
@@ -484,6 +485,11 @@ function reduceApp (state, action) {
warning: action.value || 'Incorrect password. Try again.',
})
+ case actions.UNLOCK_SUCCEEDED:
+ return extend(appState, {
+ warning: '',
+ })
+
case actions.SHOW_LOADING:
return extend(appState, {
isLoading: true,
@@ -653,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..cddcd0c1f 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: {},
@@ -41,12 +43,15 @@ function reduceMetamask (state, action) {
useBlockie: false,
featureFlags: {},
networkEndpointType: OLD_UI_NETWORK_TYPE,
+ isRevealingSeedWords: false,
}, state.metamask)
switch (action.type) {
case actions.SHOW_ACCOUNTS_PAGE:
- newState = extend(metamaskState)
+ newState = extend(metamaskState, {
+ isRevealingSeedWords: false,
+ })
delete newState.seedWords
return newState
@@ -122,10 +127,12 @@ function reduceMetamask (state, action) {
},
})
+
case actions.SHOW_NEW_VAULT_SEED:
return extend(metamaskState, {
isUnlocked: true,
isInitialized: false,
+ isRevealingSeedWords: true,
seedWords: action.value,
})
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..fc1df1f51 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()
+ },
+ }),
])
}
@@ -392,8 +361,9 @@ SendTransactionScreen.prototype.validateAmount = function (value) {
})
}
+ const verifyTokenBalance = selectedToken && tokenBalance !== null
let sufficientTokens
- if (selectedToken) {
+ if (verifyTokenBalance) {
sufficientTokens = isTokenBalanceSufficient({
tokenBalance,
amount,
@@ -408,7 +378,7 @@ SendTransactionScreen.prototype.validateAmount = function (value) {
if (conversionRate && !sufficientBalance) {
amountError = 'Insufficient funds.'
- } else if (selectedToken && !sufficientTokens) {
+ } else if (verifyTokenBalance && !sufficientTokens) {
amountError = 'Insufficient tokens.'
} else if (amountLessThanZero) {
amountError = 'Can not send negative amounts of ETH.'
@@ -427,14 +397,15 @@ SendTransactionScreen.prototype.renderAmountRow = function () {
amount,
setMaxModeTo,
maxModeOn,
+ gasTotal,
} = this.props
return h('div.send-v2__form-row', [
- h('div.send-v2__form-label', [
+ h('div.send-v2__form-label', [
'Amount:',
this.renderErrorMessage('amount'),
- !errors.amount && h('div.send-v2__amount-max', {
+ !errors.amount && gasTotal && h('div.send-v2__amount-max', {
onClick: (event) => {
event.preventDefault()
setMaxModeTo(true)
@@ -504,14 +475,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(),
@@ -530,20 +493,23 @@ SendTransactionScreen.prototype.renderFooter = function () {
goHome,
clearSend,
gasTotal,
+ tokenBalance,
+ selectedToken,
errors: { amount: amountError, to: toError },
} = this.props
+ const missingTokenBalance = selectedToken && !tokenBalance
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', {
- disabled: !noErrors || !gasTotal,
+ h('button.btn-clear.page-container__footer-button', {
+ disabled: !noErrors || !gasTotal || missingTokenBalance,
onClick: event => this.onSubmit(event),
}, 'Next'),
])
@@ -552,7 +518,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 4e25ce084..466f739d5 100644
--- a/ui/app/settings.js
+++ b/ui/app/settings.js
@@ -201,7 +201,13 @@ class Settings extends Component {
h('div.settings__content-item-col', [
h('button.settings__clear-button', {
onClick (event) {
- exportAsFile('MetaMask State Logs', window.logState())
+ window.logStateString((err, result) => {
+ if (err) {
+ this.state.dispatch(actions.displayWarning('Error in retrieving state logs.'))
+ } else {
+ exportAsFile('MetaMask State Logs.json', result)
+ }
+ })
},
}, 'Download State Logs'),
]),
@@ -250,6 +256,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 +286,7 @@ class Settings extends Component {
this.renderStateLogs(),
this.renderSeedWords(),
!isMascara && this.renderOldUI(),
+ this.renderResetAccount(),
this.renderBlockieOptIn(),
])
)
@@ -342,7 +367,7 @@ class Settings extends Component {
this.renderLogo(),
h('div.settings__info-item', [
h('div.settings__info-version-header', 'MetaMask Version'),
- h('div.settings__info-version-number', version),
+ h('div.settings__info-version-number', `${version}`),
]),
h('div.settings__info-item', [
h(
@@ -387,6 +412,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 +438,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 7a48c5f09..5e44b51ef 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -6,6 +6,8 @@ const actions = require('./actions')
const getCaretCoordinates = require('textarea-caret')
const EventEmitter = require('events').EventEmitter
const t = require('../i18n')
+const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const environmentType = require('../../app/scripts/lib/environment-type')
const Mascot = require('./components/mascot')
@@ -75,7 +77,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)',
@@ -83,6 +90,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'),
+ ]),
+
])
)
}
diff --git a/ui/index.js b/ui/index.js
index bc3676c1f..fdb2f23e0 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -25,6 +25,7 @@ function launchMetamaskUi (opts, cb) {
function startApp (metamaskState, accountManager, opts) {
// parse opts
+ if (!metamaskState.featureFlags) metamaskState.featureFlags = {}
const store = configureStore({
// metamaskState represents the cross-tab state