diff --git a/ui/app/pages/routes/index.js b/ui/app/pages/routes/index.js
index e54ed3859..a05c9df1a 100644
--- a/ui/app/pages/routes/index.js
+++ b/ui/app/pages/routes/index.js
@@ -1,419 +1 @@
-import React, { Component } from 'react'
-import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
-import { Route, Switch, withRouter, matchPath } from 'react-router-dom'
-import { compose } from 'redux'
-import * as actions from '../../store/actions'
-import log from 'loglevel'
-import IdleTimer from 'react-idle-timer'
-import {
- getNetworkIdentifier,
- preferencesSelector,
- hasPermissionRequests,
-} from '../../selectors/selectors'
-import classnames from 'classnames'
-
-// init
-import FirstTimeFlow from '../first-time-flow'
-// accounts
-import SendTransactionScreen from '../send'
-import ConfirmTransaction from '../confirm-transaction'
-
-// slideout menu
-import Sidebar from '../../components/app/sidebars'
-
-import { WALLET_VIEW_SIDEBAR } from '../../components/app/sidebars/sidebar.constants'
-
-// other views
-import Home from '../home'
-import Settings from '../settings'
-import Authenticated from '../../helpers/higher-order-components/authenticated'
-import Initialized from '../../helpers/higher-order-components/initialized'
-import Lock from '../lock'
-import PermissionsConnect from '../permissions-connect'
-import ConnectedSites from '../connected-sites'
-import RestoreVaultPage from '../keychains/restore-vault'
-import RevealSeedConfirmation from '../keychains/reveal-seed'
-import MobileSyncPage from '../mobile-sync'
-import AddTokenPage from '../add-token'
-import ConfirmAddTokenPage from '../confirm-add-token'
-import ConfirmAddSuggestedTokenPage from '../confirm-add-suggested-token'
-import CreateAccountPage from '../create-account'
-
-import Loading from '../../components/ui/loading-screen'
-import LoadingNetwork from '../../components/app/loading-network-screen'
-import NetworkDropdown from '../../components/app/dropdowns/network-dropdown'
-import AccountMenu from '../../components/app/account-menu'
-
-// Global Modals
-import { Modal } from '../../components/app/modals'
-
-// Global Alert
-import Alert from '../../components/ui/alert'
-
-import AppHeader from '../../components/app/app-header'
-import UnlockPage from '../unlock-page'
-
-import {
- submittedPendingTransactionsSelector,
-} from '../../selectors/transactions'
-
-// Routes
-import {
- DEFAULT_ROUTE,
- LOCK_ROUTE,
- UNLOCK_ROUTE,
- SETTINGS_ROUTE,
- REVEAL_SEED_ROUTE,
- MOBILE_SYNC_ROUTE,
- RESTORE_VAULT_ROUTE,
- ADD_TOKEN_ROUTE,
- CONFIRM_ADD_TOKEN_ROUTE,
- CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
- NEW_ACCOUNT_ROUTE,
- SEND_ROUTE,
- CONFIRM_TRANSACTION_ROUTE,
- INITIALIZE_ROUTE,
- INITIALIZE_UNLOCK_ROUTE,
- CONNECT_ROUTE,
- CONNECTED_ROUTE,
-} from '../../helpers/constants/routes'
-
-// enums
-import {
- ENVIRONMENT_TYPE_NOTIFICATION,
- ENVIRONMENT_TYPE_POPUP,
-} from '../../../../app/scripts/lib/enums'
-
-class Routes extends Component {
- UNSAFE_componentWillMount () {
- const { currentCurrency, setCurrentCurrencyToUSD } = this.props
-
- if (!currentCurrency) {
- setCurrentCurrencyToUSD()
- }
-
- this.props.history.listen((locationObj, action) => {
- if (action === 'PUSH') {
- const url = `&url=${encodeURIComponent('http://www.metamask.io/metametrics' + locationObj.pathname)}`
- this.context.metricsEvent({}, {
- currentPath: '',
- pathname: locationObj.pathname,
- url,
- pageOpts: {
- hideDimensions: true,
- },
- })
- }
- })
- }
-
- renderRoutes () {
- const { autoLockTimeLimit, setLastActiveTime } = this.props
-
- const routes = (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-
- if (autoLockTimeLimit > 0) {
- return (
-
- {routes}
-
- )
- }
-
- return routes
- }
-
- onInitializationUnlockPage () {
- const { location } = this.props
- return Boolean(matchPath(location.pathname, { path: INITIALIZE_UNLOCK_ROUTE, exact: true }))
- }
-
- onConfirmPage () {
- const { location } = this.props
- return Boolean(matchPath(location.pathname, { path: CONFIRM_TRANSACTION_ROUTE, exact: false }))
- }
-
- hideAppHeader () {
- const { location, hasPermissionsRequests } = this.props
-
- const isInitializing = Boolean(matchPath(location.pathname, {
- path: INITIALIZE_ROUTE, exact: false,
- }))
-
- if (isInitializing && !this.onInitializationUnlockPage()) {
- return true
- }
-
- if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_NOTIFICATION) {
- return true
- }
-
- if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_POPUP) {
- return this.onConfirmPage() || hasPermissionsRequests
- }
-
- const isHandlingPermissionsRequest = Boolean(matchPath(location.pathname, {
- path: CONNECT_ROUTE, exact: false,
- }))
-
- if (hasPermissionsRequests || isHandlingPermissionsRequest) {
- return true
- }
- }
-
- render () {
- const {
- isLoading,
- alertMessage,
- textDirection,
- loadingMessage,
- network,
- provider,
- frequentRpcListDetail,
- setMouseUserState,
- sidebar,
- submittedPendingTransactions,
- isMouseUser,
- } = this.props
- const isLoadingNetwork = network === 'loading'
- const loadMessage = loadingMessage || isLoadingNetwork ?
- this.getConnectingLabel(loadingMessage) : null
- log.debug('Main ui render function')
-
- const {
- isOpen: sidebarIsOpen,
- transitionName: sidebarTransitionName,
- type: sidebarType,
- props,
- } = sidebar
- const { transaction: sidebarTransaction } = props || {}
-
- const sidebarOnOverlayClose = sidebarType === WALLET_VIEW_SIDEBAR
- ? () => {
- this.context.metricsEvent({
- eventOpts: {
- category: 'Navigation',
- action: 'Wallet Sidebar',
- name: 'Closed Sidebare Via Overlay',
- },
- })
- }
- : null
-
- const sidebarShouldClose = sidebarTransaction &&
- !sidebarTransaction.status === 'failed' &&
- !submittedPendingTransactions.find(({ id }) => id === sidebarTransaction.id)
-
- return (
-
setMouseUserState(true)}
- onKeyDown={(e) => {
- if (e.keyCode === 9) {
- setMouseUserState(false)
- }
- }}
- >
-
-
- {
- !this.hideAppHeader() && (
-
- )
- }
-
-
-
-
- { isLoading && }
- { !isLoading && isLoadingNetwork && }
- { this.renderRoutes() }
-
-
- )
- }
-
- toggleMetamaskActive () {
- if (!this.props.isUnlocked) {
- // currently inactive: redirect to password box
- const passwordBox = document.querySelector('input[type=password]')
- if (!passwordBox) {
- return
- }
- passwordBox.focus()
- } else {
- // currently active: deactivate
- this.props.lockMetaMask()
- }
- }
-
- getConnectingLabel = function (loadingMessage) {
- if (loadingMessage) {
- return loadingMessage
- }
- const { provider, providerId } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = this.context.t('connectingToMainnet')
- } else if (providerName === 'ropsten') {
- name = this.context.t('connectingToRopsten')
- } else if (providerName === 'kovan') {
- name = this.context.t('connectingToKovan')
- } else if (providerName === 'rinkeby') {
- name = this.context.t('connectingToRinkeby')
- } else if (providerName === 'localhost') {
- name = this.context.t('connectingToLocalhost')
- } else if (providerName === 'goerli') {
- name = this.context.t('connectingToGoerli')
- } else {
- name = this.context.t('connectingTo', [providerId])
- }
-
- return name
- }
-
- getNetworkName () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = this.context.t('mainnet')
- } else if (providerName === 'ropsten') {
- name = this.context.t('ropsten')
- } else if (providerName === 'kovan') {
- name = this.context.t('kovan')
- } else if (providerName === 'rinkeby') {
- name = this.context.t('rinkeby')
- } else if (providerName === 'localhost') {
- name = this.context.t('localhost')
- } else if (providerName === 'goerli') {
- name = this.context.t('goerli')
- } else {
- name = this.context.t('unknownNetwork')
- }
-
- return name
- }
-}
-
-Routes.propTypes = {
- currentCurrency: PropTypes.string,
- setCurrentCurrencyToUSD: PropTypes.func,
- isLoading: PropTypes.bool,
- loadingMessage: PropTypes.string,
- alertMessage: PropTypes.string,
- textDirection: PropTypes.string,
- network: PropTypes.string,
- provider: PropTypes.object,
- frequentRpcListDetail: PropTypes.array,
- sidebar: PropTypes.object,
- alertOpen: PropTypes.bool,
- hideSidebar: PropTypes.func,
- isUnlocked: PropTypes.bool,
- setLastActiveTime: PropTypes.func,
- history: PropTypes.object,
- location: PropTypes.object,
- lockMetaMask: PropTypes.func,
- submittedPendingTransactions: PropTypes.array,
- isMouseUser: PropTypes.bool,
- setMouseUserState: PropTypes.func,
- providerId: PropTypes.string,
- hasPermissionsRequests: PropTypes.bool,
- autoLockTimeLimit: PropTypes.number,
-}
-
-function mapStateToProps (state) {
- const { appState } = state
- const {
- sidebar,
- alertOpen,
- alertMessage,
- isLoading,
- loadingMessage,
- } = appState
-
- const { autoLockTimeLimit = 0 } = preferencesSelector(state)
-
- return {
- // state from plugin
- sidebar,
- alertOpen,
- alertMessage,
- textDirection: state.metamask.textDirection,
- isLoading,
- loadingMessage,
- isUnlocked: state.metamask.isUnlocked,
- submittedPendingTransactions: submittedPendingTransactionsSelector(state),
- network: state.metamask.network,
- provider: state.metamask.provider,
- frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
- currentCurrency: state.metamask.currentCurrency,
- isMouseUser: state.appState.isMouseUser,
- providerId: getNetworkIdentifier(state),
- autoLockTimeLimit,
- hasPermissionsRequests: hasPermissionRequests(state),
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- lockMetaMask: () => dispatch(actions.lockMetamask(false)),
- hideSidebar: () => dispatch(actions.hideSidebar()),
- setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
- setMouseUserState: (isMouseUser) => dispatch(actions.setMouseUserState(isMouseUser)),
- setLastActiveTime: () => dispatch(actions.setLastActiveTime()),
- }
-}
-
-Routes.contextTypes = {
- t: PropTypes.func,
- metricsEvent: PropTypes.func,
-}
-
-export default compose(
- withRouter,
- connect(mapStateToProps, mapDispatchToProps)
-)(Routes)
+export { default } from './routes.container'
diff --git a/ui/app/pages/routes/routes.component.js b/ui/app/pages/routes/routes.component.js
new file mode 100644
index 000000000..ce913ca1b
--- /dev/null
+++ b/ui/app/pages/routes/routes.component.js
@@ -0,0 +1,328 @@
+import classnames from 'classnames'
+import PropTypes from 'prop-types'
+import React, { Component } from 'react'
+import { matchPath, Route, Switch } from 'react-router-dom'
+import IdleTimer from 'react-idle-timer'
+
+import FirstTimeFlow from '../first-time-flow'
+import SendTransactionScreen from '../send'
+import ConfirmTransaction from '../confirm-transaction'
+import Sidebar from '../../components/app/sidebars'
+import { WALLET_VIEW_SIDEBAR } from '../../components/app/sidebars/sidebar.constants'
+import Home from '../home'
+import Settings from '../settings'
+import Authenticated from '../../helpers/higher-order-components/authenticated'
+import Initialized from '../../helpers/higher-order-components/initialized'
+import Lock from '../lock'
+import PermissionsConnect from '../permissions-connect'
+import ConnectedSites from '../connected-sites'
+import RestoreVaultPage from '../keychains/restore-vault'
+import RevealSeedConfirmation from '../keychains/reveal-seed'
+import MobileSyncPage from '../mobile-sync'
+import AddTokenPage from '../add-token'
+import ConfirmAddTokenPage from '../confirm-add-token'
+import ConfirmAddSuggestedTokenPage from '../confirm-add-suggested-token'
+import CreateAccountPage from '../create-account'
+import Loading from '../../components/ui/loading-screen'
+import LoadingNetwork from '../../components/app/loading-network-screen'
+import NetworkDropdown from '../../components/app/dropdowns/network-dropdown'
+import AccountMenu from '../../components/app/account-menu'
+import { Modal } from '../../components/app/modals'
+import Alert from '../../components/ui/alert'
+import AppHeader from '../../components/app/app-header'
+import UnlockPage from '../unlock-page'
+
+import {
+ ADD_TOKEN_ROUTE,
+ CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
+ CONFIRM_ADD_TOKEN_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ CONNECT_ROUTE,
+ CONNECTED_ROUTE,
+ DEFAULT_ROUTE,
+ INITIALIZE_ROUTE,
+ INITIALIZE_UNLOCK_ROUTE,
+ LOCK_ROUTE,
+ MOBILE_SYNC_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ REVEAL_SEED_ROUTE,
+ SEND_ROUTE,
+ SETTINGS_ROUTE,
+ UNLOCK_ROUTE,
+} from '../../helpers/constants/routes'
+
+import { ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums'
+
+export default class Routes extends Component {
+ static propTypes = {
+ currentCurrency: PropTypes.string,
+ setCurrentCurrencyToUSD: PropTypes.func,
+ isLoading: PropTypes.bool,
+ loadingMessage: PropTypes.string,
+ alertMessage: PropTypes.string,
+ textDirection: PropTypes.string,
+ network: PropTypes.string,
+ provider: PropTypes.object,
+ frequentRpcListDetail: PropTypes.array,
+ sidebar: PropTypes.object,
+ alertOpen: PropTypes.bool,
+ hideSidebar: PropTypes.func,
+ isUnlocked: PropTypes.bool,
+ setLastActiveTime: PropTypes.func,
+ history: PropTypes.object,
+ location: PropTypes.object,
+ lockMetaMask: PropTypes.func,
+ submittedPendingTransactions: PropTypes.array,
+ isMouseUser: PropTypes.bool,
+ setMouseUserState: PropTypes.func,
+ providerId: PropTypes.string,
+ hasPermissionsRequests: PropTypes.bool,
+ autoLockTimeLimit: PropTypes.number,
+ }
+
+ static contextTypes = {
+ t: PropTypes.func,
+ metricsEvent: PropTypes.func,
+ }
+
+ UNSAFE_componentWillMount () {
+ const { currentCurrency, setCurrentCurrencyToUSD } = this.props
+
+ if (!currentCurrency) {
+ setCurrentCurrencyToUSD()
+ }
+
+ this.props.history.listen((locationObj, action) => {
+ if (action === 'PUSH') {
+ const url = `&url=${encodeURIComponent('http://www.metamask.io/metametrics' + locationObj.pathname)}`
+ this.context.metricsEvent({}, {
+ currentPath: '',
+ pathname: locationObj.pathname,
+ url,
+ pageOpts: {
+ hideDimensions: true,
+ },
+ })
+ }
+ })
+ }
+
+ renderRoutes () {
+ const { autoLockTimeLimit, setLastActiveTime } = this.props
+
+ const routes = (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+
+ if (autoLockTimeLimit > 0) {
+ return (
+
+ {routes}
+
+ )
+ }
+
+ return routes
+ }
+
+ onInitializationUnlockPage () {
+ const { location } = this.props
+ return Boolean(matchPath(location.pathname, { path: INITIALIZE_UNLOCK_ROUTE, exact: true }))
+ }
+
+ onConfirmPage () {
+ const { location } = this.props
+ return Boolean(matchPath(location.pathname, { path: CONFIRM_TRANSACTION_ROUTE, exact: false }))
+ }
+
+ hideAppHeader () {
+ const { location, hasPermissionsRequests } = this.props
+
+ const isInitializing = Boolean(matchPath(location.pathname, {
+ path: INITIALIZE_ROUTE, exact: false,
+ }))
+
+ if (isInitializing && !this.onInitializationUnlockPage()) {
+ return true
+ }
+
+ if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_NOTIFICATION) {
+ return true
+ }
+
+ if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_POPUP) {
+ return this.onConfirmPage() || hasPermissionsRequests
+ }
+
+ const isHandlingPermissionsRequest = Boolean(matchPath(location.pathname, {
+ path: CONNECT_ROUTE, exact: false,
+ }))
+
+ if (hasPermissionsRequests || isHandlingPermissionsRequest) {
+ return true
+ }
+ }
+
+ render () {
+ const {
+ isLoading,
+ alertMessage,
+ textDirection,
+ loadingMessage,
+ network,
+ provider,
+ frequentRpcListDetail,
+ setMouseUserState,
+ sidebar,
+ submittedPendingTransactions,
+ isMouseUser,
+ } = this.props
+ const isLoadingNetwork = network === 'loading'
+ const loadMessage = (loadingMessage || isLoadingNetwork)
+ ? this.getConnectingLabel(loadingMessage)
+ : null
+
+ const {
+ isOpen: sidebarIsOpen,
+ transitionName: sidebarTransitionName,
+ type: sidebarType,
+ props,
+ } = sidebar
+ const { transaction: sidebarTransaction } = props || {}
+
+ const sidebarOnOverlayClose = sidebarType === WALLET_VIEW_SIDEBAR
+ ? () => {
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Navigation',
+ action: 'Wallet Sidebar',
+ name: 'Closed Sidebare Via Overlay',
+ },
+ })
+ }
+ : null
+
+ const sidebarShouldClose = sidebarTransaction &&
+ !sidebarTransaction.status === 'failed' &&
+ !submittedPendingTransactions.find(({ id }) => id === sidebarTransaction.id)
+
+ return (
+ setMouseUserState(true)}
+ onKeyDown={(e) => {
+ if (e.keyCode === 9) {
+ setMouseUserState(false)
+ }
+ }}
+ >
+
+
+ { !this.hideAppHeader() && (
+
+ ) }
+
+
+
+
+ { isLoading && }
+ { !isLoading && isLoadingNetwork && }
+ { this.renderRoutes() }
+
+
+ )
+ }
+
+ toggleMetamaskActive () {
+ if (!this.props.isUnlocked) {
+ // currently inactive: redirect to password box
+ const passwordBox = document.querySelector('input[type=password]')
+ if (!passwordBox) {
+ return
+ }
+ passwordBox.focus()
+ } else {
+ // currently active: deactivate
+ this.props.lockMetaMask()
+ }
+ }
+
+ getConnectingLabel (loadingMessage) {
+ if (loadingMessage) {
+ return loadingMessage
+ }
+ const { provider, providerId } = this.props
+
+ switch (provider.type) {
+ case 'mainnet':
+ return this.context.t('connectingToMainnet')
+ case 'ropsten':
+ return this.context.t('connectingToRopsten')
+ case 'kovan':
+ return this.context.t('connectingToKovan')
+ case 'rinkeby':
+ return this.context.t('connectingToRinkeby')
+ case 'localhost':
+ return this.context.t('connectingToLocalhost')
+ case 'goerli':
+ return this.context.t('connectingToGoerli')
+ default:
+ return this.context.t('connectingTo', [providerId])
+ }
+ }
+
+ getNetworkName () {
+ switch (this.props.provider.type) {
+ case 'mainnet':
+ return this.context.t('mainnet')
+ case 'ropsten':
+ return this.context.t('ropsten')
+ case 'kovan':
+ return this.context.t('kovan')
+ case 'rinkeby':
+ return this.context.t('rinkeby')
+ case 'localhost':
+ return this.context.t('localhost')
+ case 'goerli':
+ return this.context.t('goerli')
+ default:
+ return this.context.t('unknownNetwork')
+ }
+ }
+}
diff --git a/ui/app/pages/routes/routes.container.js b/ui/app/pages/routes/routes.container.js
new file mode 100644
index 000000000..0c3f5fad6
--- /dev/null
+++ b/ui/app/pages/routes/routes.container.js
@@ -0,0 +1,60 @@
+import { connect } from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'redux'
+import {
+ getNetworkIdentifier,
+ hasPermissionRequests,
+ preferencesSelector,
+} from '../../selectors/selectors'
+import { submittedPendingTransactionsSelector } from '../../selectors/transactions'
+import Routes from './routes.component'
+import {
+ hideSidebar,
+ lockMetamask,
+ setCurrentCurrency,
+ setLastActiveTime,
+ setMouseUserState,
+} from '../../store/actions'
+
+function mapStateToProps (state) {
+ const { appState } = state
+ const {
+ sidebar,
+ alertOpen,
+ alertMessage,
+ isLoading,
+ loadingMessage,
+ } = appState
+ const { autoLockTimeLimit = 0 } = preferencesSelector(state)
+
+ return {
+ sidebar,
+ alertOpen,
+ alertMessage,
+ textDirection: state.metamask.textDirection,
+ isLoading,
+ loadingMessage,
+ isUnlocked: state.metamask.isUnlocked,
+ submittedPendingTransactions: submittedPendingTransactionsSelector(state),
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
+ currentCurrency: state.metamask.currentCurrency,
+ isMouseUser: state.appState.isMouseUser,
+ providerId: getNetworkIdentifier(state),
+ autoLockTimeLimit,
+ hasPermissionsRequests: hasPermissionRequests(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ lockMetaMask: () => dispatch(lockMetamask(false)),
+ hideSidebar: () => dispatch(hideSidebar()),
+ setCurrentCurrencyToUSD: () => dispatch(setCurrentCurrency('usd')),
+ setMouseUserState: (isMouseUser) => dispatch(setMouseUserState(isMouseUser)),
+ setLastActiveTime: () => dispatch(setLastActiveTime()),
+ }
+}
+
+export default compose(withRouter, connect(mapStateToProps, mapDispatchToProps))(Routes)