1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-23 11:46:13 +02:00
metamask-extension/ui/app/pages/routes/index.js

406 lines
12 KiB
JavaScript
Raw Normal View History

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 'recompose'
import actions from '../../store/actions'
import log from 'loglevel'
import IdleTimer from 'react-idle-timer'
import {getNetworkIdentifier, preferencesSelector} from '../../selectors/selectors'
import classnames from 'classnames'
2018-01-10 01:45:39 +01:00
// init
import FirstTimeFlow from '../first-time-flow'
// accounts
Use `AdvancedGasInputs` in `AdvancedTabContent` (#7186) * Use `AdvancedGasInputs` in `AdvancedTabContent` The `AdvancedGasInputs` component was originally extracted from the `AdvancedTabContent` component, duplicating much of the rendering logic. They have since evolved separately, with bugs being fixed in one place but not the other. The inputs and outputs expected weren't exactly the same, as the `AdvancedGasInputs` component converts the input custom gas price and limit, and it converts them both in the setter methods as well. The `GasModalPageContainer` had to be adjusted to avoid converting these values multiple times. Both components dealt with input debouncing separately, both in less than ideal ways. `AdvancedTabContent` didn't debounce either field, but it did debounce the check for whether the gas limit field was below the minimum value. So if a less-than-minimum value was set, it would be propogated upwards and could be saved if the user clicked 'Save' quickly enough. After a second delay it would snap back to the minimum value. The `AdvancedGasInputs` component debounced both fields, but it would replace any gas limit below the minimum with the minimum value. This led to a problem where a brief pause during typing would reset the field to 21000. The `AdvancedGasInputs` approach was chosen, except that it was updated to no longer change the gas limit if it was below the minimum. Instead it displays an error. Parent components were checked to ensure they would detect the error case of the gas limit being set too low, and prevent the form submission in those cases. Of the three parents, one had already dealt with it correctly, one needed to convert the gas limit from hex first, and another needed the gas limit check added. Closes #6872 * Cleanup send components Empty README files have been removed, and a mistake in the index file for the send page has been corrected. The Gas Slider component class name was updated as well; it looks like it was originally created from `AdvancedTabContent`, so it still had that class name.
2019-10-23 14:23:15 +02:00
import SendTransactionScreen from '../send'
const ConfirmTransaction = require('../confirm-transaction')
// slideout menu
const Sidebar = require('../../components/app/sidebars').default
const { WALLET_VIEW_SIDEBAR } = require('../../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'
const RestoreVaultPage = require('../keychains/restore-vault').default
const RevealSeedConfirmation = require('../keychains/reveal-seed')
const MobileSyncPage = require('../mobile-sync')
const AddTokenPage = require('../add-token')
const ConfirmAddTokenPage = require('../confirm-add-token')
const ConfirmAddSuggestedTokenPage = require('../confirm-add-suggested-token')
import CreateAccountPage from '../create-account'
const Loading = require('../../components/ui/loading-screen')
const LoadingNetwork = require('../../components/app/loading-network-screen').default
const NetworkDropdown = require('../../components/app/dropdowns/network-dropdown')
import AccountMenu from '../../components/app/account-menu'
// Global Modals
const Modal = require('../../components/app/modals').Modal
2018-07-19 08:31:02 +02:00
// Global Alert
const Alert = require('../../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,
2019-02-25 20:10:13 +01:00
MOBILE_SYNC_ROUTE,
RESTORE_VAULT_ROUTE,
ADD_TOKEN_ROUTE,
2018-05-20 08:04:19 +02:00
CONFIRM_ADD_TOKEN_ROUTE,
CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
NEW_ACCOUNT_ROUTE,
SEND_ROUTE,
CONFIRM_TRANSACTION_ROUTE,
2017-12-04 07:24:30 +01:00
INITIALIZE_ROUTE,
INITIALIZE_UNLOCK_ROUTE,
} from '../../helpers/constants/routes'
// enums
import {
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP,
} from '../../../../app/scripts/lib/enums'
class Routes extends Component {
componentWillMount () {
const { currentCurrency, setCurrentCurrencyToUSD } = this.props
if (!currentCurrency) {
setCurrentCurrencyToUSD()
}
Metametrics (#6171) * Add metametrics provider and util. * Add backend api and state for participating in metametrics. * Add frontend action for participating in metametrics. * Add metametrics opt-in screen. * Add metametrics events to first time flow. * Add metametrics events for route changes * Add metametrics events for send and confirm screens * Add metametrics events to dropdowns, transactions, log in and out, settings, sig requests and main screen * Ensures each log in is measured as a new visit by metametrics. * Ensure metametrics is called with an empty string for dimensions params if specified * Adds opt in metametrics modal after unlock for existing users * Adds settings page toggle for opting in and out of MetaMetrics * Switch metametrics dimensions to page level scope * Lint, test and translation fixes for metametrics. * Update design for metametrics opt-in screen * Complete responsive styling of metametrics-opt-in modal * Use new chart image on metrics opt in screens * Incorporate the metametrics opt-in screen into the new onboarding flow * Update e2e tests to accomodate metametrics changes * Mock out metametrics network requests in integration tests * Fix tx-list integration test to support metametrics provider. * Send number of tokens and accounts data with every metametrics event. * Update metametrics event descriptor schema and add new events. * Fix import tos bug and send gas button bug due to metametrics changes. * Various small fixes on the metametrics branch. * Add origin custom variable type to metametrics.util * Fix names of onboarding complete actions (metametrics). * Fix names of Metrics Options actions (metametrics). * Clean up code related to metametrics. * Fix bad merge conflict resolution and improve promise handling in sendMetaMetrics event and confrim tx base * Don't send a second metrics event if user has gone back during first time flow. * Collect metametrics on going back from onboarding create/import. * Add missing custom variable constants for metametrics * Fix metametrics provider * Make height of opt-in modal responsive. * Adjust text content for opt-in modal. * Update metametrics event names and clean up code in opt-in-modal * Put phishing warning step next to last in onboarding flow * Link terms of service on create and import screens of first time flow * Add subtext to options on the onboarding select action screen. * Fix styling of bullet points on end of onboarding screen. * Combine phishing warning and congratulations screens. * Fix placement of users if unlocking after an incomplete onboarding import flow. * Fix capitalization in opt-in screen * Fix last onboarding screen translations * Add link to 'Learn More' on the last screen of onboarding * Code clean up: metametrics branch * Update e2e tests for phishing warning step removal * e2e tests passing on metametrics branch * Different tracking urls for metametrics on development and prod
2019-03-05 16:45:01 +01:00
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,
},
})
}
})
2017-08-07 04:03:38 +02:00
}
renderRoutes () {
const { autoLogoutTimeLimit, setLastActiveTime } = this.props
const routes = (
<Switch>
<Route path={LOCK_ROUTE} component={Lock} exact />
<Route path={INITIALIZE_ROUTE} component={FirstTimeFlow} />
<Initialized path={UNLOCK_ROUTE} component={UnlockPage} exact />
<Initialized path={RESTORE_VAULT_ROUTE} component={RestoreVaultPage} exact />
<Authenticated path={REVEAL_SEED_ROUTE} component={RevealSeedConfirmation} exact />
2019-02-25 20:10:13 +01:00
<Authenticated path={MOBILE_SYNC_ROUTE} component={MobileSyncPage} exact />
<Authenticated path={SETTINGS_ROUTE} component={Settings} />
<Authenticated path={`${CONFIRM_TRANSACTION_ROUTE}/:id?`} component={ConfirmTransaction} />
<Authenticated path={SEND_ROUTE} component={SendTransactionScreen} exact />
<Authenticated path={ADD_TOKEN_ROUTE} component={AddTokenPage} exact />
<Authenticated path={CONFIRM_ADD_TOKEN_ROUTE} component={ConfirmAddTokenPage} exact />
<Authenticated path={CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE} component={ConfirmAddSuggestedTokenPage} exact />
<Authenticated path={NEW_ACCOUNT_ROUTE} component={CreateAccountPage} />
<Authenticated path={DEFAULT_ROUTE} component={Home} exact />
</Switch>
)
if (autoLogoutTimeLimit > 0) {
return (
<IdleTimer onAction={setLastActiveTime} throttle={1000}>
{routes}
</IdleTimer>
)
}
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 }))
}
hasProviderRequests () {
const { providerRequests } = this.props
return Array.isArray(providerRequests) && providerRequests.length > 0
}
hideAppHeader () {
const { location } = 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() || this.hasProviderRequests()
}
}
render () {
2017-12-04 09:06:09 +01:00
const {
isLoading,
2018-07-19 08:31:02 +02:00
alertMessage,
textDirection,
2017-12-04 09:06:09 +01:00
loadingMessage,
network,
provider,
frequentRpcListDetail,
2017-12-04 09:06:09 +01:00
currentView,
2018-03-27 09:20:35 +02:00
setMouseUserState,
sidebar,
submittedPendingTransactions,
isMouseUser,
2017-12-04 09:06:09 +01:00
} = this.props
const isLoadingNetwork = network === 'loading' && currentView.name !== 'config'
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 (
<div
className={classnames('app', { 'mouse-user-styles': isMouseUser})}
dir={textDirection}
onClick={() => setMouseUserState(true)}
onKeyDown={e => {
2018-03-27 09:20:35 +02:00
if (e.keyCode === 9) {
setMouseUserState(false)
}
}}
>
<Modal />
<Alert
visible={this.props.alertOpen}
msg={alertMessage}
/>
{
!this.hideAppHeader() && (
<AppHeader
hideNetworkIndicator={this.onInitializationUnlockPage()}
disabled={this.onConfirmPage()}
/>
)
}
<Sidebar
sidebarOpen={sidebarIsOpen}
sidebarShouldClose={sidebarShouldClose}
hideSidebar={this.props.hideSidebar}
transitionName={sidebarTransitionName}
type={sidebarType}
sidebarProps={sidebar.props}
Metametrics (#6171) * Add metametrics provider and util. * Add backend api and state for participating in metametrics. * Add frontend action for participating in metametrics. * Add metametrics opt-in screen. * Add metametrics events to first time flow. * Add metametrics events for route changes * Add metametrics events for send and confirm screens * Add metametrics events to dropdowns, transactions, log in and out, settings, sig requests and main screen * Ensures each log in is measured as a new visit by metametrics. * Ensure metametrics is called with an empty string for dimensions params if specified * Adds opt in metametrics modal after unlock for existing users * Adds settings page toggle for opting in and out of MetaMetrics * Switch metametrics dimensions to page level scope * Lint, test and translation fixes for metametrics. * Update design for metametrics opt-in screen * Complete responsive styling of metametrics-opt-in modal * Use new chart image on metrics opt in screens * Incorporate the metametrics opt-in screen into the new onboarding flow * Update e2e tests to accomodate metametrics changes * Mock out metametrics network requests in integration tests * Fix tx-list integration test to support metametrics provider. * Send number of tokens and accounts data with every metametrics event. * Update metametrics event descriptor schema and add new events. * Fix import tos bug and send gas button bug due to metametrics changes. * Various small fixes on the metametrics branch. * Add origin custom variable type to metametrics.util * Fix names of onboarding complete actions (metametrics). * Fix names of Metrics Options actions (metametrics). * Clean up code related to metametrics. * Fix bad merge conflict resolution and improve promise handling in sendMetaMetrics event and confrim tx base * Don't send a second metrics event if user has gone back during first time flow. * Collect metametrics on going back from onboarding create/import. * Add missing custom variable constants for metametrics * Fix metametrics provider * Make height of opt-in modal responsive. * Adjust text content for opt-in modal. * Update metametrics event names and clean up code in opt-in-modal * Put phishing warning step next to last in onboarding flow * Link terms of service on create and import screens of first time flow * Add subtext to options on the onboarding select action screen. * Fix styling of bullet points on end of onboarding screen. * Combine phishing warning and congratulations screens. * Fix placement of users if unlocking after an incomplete onboarding import flow. * Fix capitalization in opt-in screen * Fix last onboarding screen translations * Add link to 'Learn More' on the last screen of onboarding * Code clean up: metametrics branch * Update e2e tests for phishing warning step removal * e2e tests passing on metametrics branch * Different tracking urls for metametrics on development and prod
2019-03-05 16:45:01 +01:00
onOverlayClose={sidebarOnOverlayClose}
/>
<NetworkDropdown
provider={provider}
frequentRpcListDetail={frequentRpcListDetail}
/>
<AccountMenu />
<div className="main-container-wrapper">
{ isLoading && <Loading loadingMessage={loadMessage} /> }
{ !isLoading && isLoadingNetwork && <LoadingNetwork /> }
{ this.renderRoutes() }
</div>
</div>
)
}
2017-08-08 22:37:41 +02:00
toggleMetamaskActive () {
if (!this.props.isUnlocked) {
// currently inactive: redirect to password box
var 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
2018-03-27 09:20:35 +02:00
const providerName = provider.type
let name
if (providerName === 'mainnet') {
2018-03-31 01:18:48 +02:00
name = this.context.t('connectingToMainnet')
2018-03-27 09:20:35 +02:00
} else if (providerName === 'ropsten') {
2018-03-31 01:18:48 +02:00
name = this.context.t('connectingToRopsten')
2018-03-27 09:20:35 +02:00
} else if (providerName === 'kovan') {
name = this.context.t('connectingToKovan')
2018-03-27 09:20:35 +02:00
} else if (providerName === 'rinkeby') {
2018-03-31 01:18:48 +02:00
name = this.context.t('connectingToRinkeby')
} else if (providerName === 'localhost') {
name = this.context.t('connectingToLocalhost')
2019-04-17 19:34:49 +02:00
} else if (providerName === 'goerli') {
name = this.context.t('connectingToGoerli')
2018-03-27 09:20:35 +02:00
} else {
name = this.context.t('connectingTo', [providerId])
2018-03-27 09:20:35 +02:00
}
return name
2018-03-19 19:28:02 +01:00
}
getNetworkName () {
const { provider } = this.props
const providerName = provider.type
let name
if (providerName === 'mainnet') {
2018-03-31 01:18:48 +02:00
name = this.context.t('mainnet')
} else if (providerName === 'ropsten') {
2018-03-31 01:18:48 +02:00
name = this.context.t('ropsten')
} else if (providerName === 'kovan') {
2018-03-31 01:18:48 +02:00
name = this.context.t('kovan')
} else if (providerName === 'rinkeby') {
2018-03-31 01:18:48 +02:00
name = this.context.t('rinkeby')
} else if (providerName === 'localhost') {
name = this.context.t('localhost')
2019-04-17 19:34:49 +02:00
} else if (providerName === 'goerli') {
name = this.context.t('goerli')
} else {
2018-03-31 01:18:48 +02:00
name = this.context.t('unknownNetwork')
}
return name
2016-05-14 03:07:47 +02:00
}
}
2016-06-29 02:57:53 +02:00
Routes.propTypes = {
2017-12-04 09:06:09 +01:00
currentCurrency: PropTypes.string,
setCurrentCurrencyToUSD: PropTypes.func,
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
2018-07-19 08:31:02 +02:00
alertMessage: PropTypes.string,
textDirection: PropTypes.string,
2017-12-04 09:06:09 +01:00
network: PropTypes.string,
provider: PropTypes.object,
frequentRpcListDetail: PropTypes.array,
2017-12-04 09:06:09 +01:00
currentView: PropTypes.object,
sidebar: PropTypes.object,
2018-07-19 08:31:02 +02:00
alertOpen: PropTypes.bool,
2017-12-04 09:06:09 +01:00
hideSidebar: PropTypes.func,
isUnlocked: PropTypes.bool,
setLastActiveTime: PropTypes.func,
2017-12-04 09:06:09 +01:00
history: PropTypes.object,
location: PropTypes.object,
lockMetaMask: PropTypes.func,
submittedPendingTransactions: PropTypes.array,
2018-03-27 09:20:35 +02:00
isMouseUser: PropTypes.bool,
setMouseUserState: PropTypes.func,
providerId: PropTypes.string,
providerRequests: PropTypes.array,
autoLogoutTimeLimit: PropTypes.number,
2017-12-04 09:06:09 +01:00
}
function mapStateToProps (state) {
const { appState, metamask } = state
const {
sidebar,
2018-07-19 08:31:02 +02:00
alertOpen,
alertMessage,
isLoading,
loadingMessage,
} = appState
const { autoLogoutTimeLimit = 0 } = preferencesSelector(state)
return {
// state from plugin
sidebar,
2018-07-19 08:31:02 +02:00
alertOpen,
alertMessage,
textDirection: state.metamask.textDirection,
isLoading,
loadingMessage,
isUnlocked: state.metamask.isUnlocked,
currentView: state.appState.currentView,
submittedPendingTransactions: submittedPendingTransactionsSelector(state),
network: state.metamask.network,
provider: state.metamask.provider,
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
currentCurrency: state.metamask.currentCurrency,
2018-03-27 09:20:35 +02:00
isMouseUser: state.appState.isMouseUser,
providerId: getNetworkIdentifier(state),
autoLogoutTimeLimit,
providerRequests: metamask.providerRequests,
}
}
function mapDispatchToProps (dispatch) {
return {
lockMetaMask: () => dispatch(actions.lockMetamask(false)),
hideSidebar: () => dispatch(actions.hideSidebar()),
setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
2018-03-27 09:20:35 +02:00
setMouseUserState: (isMouseUser) => dispatch(actions.setMouseUserState(isMouseUser)),
setLastActiveTime: () => dispatch(actions.setLastActiveTime()),
}
}
Routes.contextTypes = {
2018-03-31 02:37:24 +02:00
t: PropTypes.func,
Metametrics (#6171) * Add metametrics provider and util. * Add backend api and state for participating in metametrics. * Add frontend action for participating in metametrics. * Add metametrics opt-in screen. * Add metametrics events to first time flow. * Add metametrics events for route changes * Add metametrics events for send and confirm screens * Add metametrics events to dropdowns, transactions, log in and out, settings, sig requests and main screen * Ensures each log in is measured as a new visit by metametrics. * Ensure metametrics is called with an empty string for dimensions params if specified * Adds opt in metametrics modal after unlock for existing users * Adds settings page toggle for opting in and out of MetaMetrics * Switch metametrics dimensions to page level scope * Lint, test and translation fixes for metametrics. * Update design for metametrics opt-in screen * Complete responsive styling of metametrics-opt-in modal * Use new chart image on metrics opt in screens * Incorporate the metametrics opt-in screen into the new onboarding flow * Update e2e tests to accomodate metametrics changes * Mock out metametrics network requests in integration tests * Fix tx-list integration test to support metametrics provider. * Send number of tokens and accounts data with every metametrics event. * Update metametrics event descriptor schema and add new events. * Fix import tos bug and send gas button bug due to metametrics changes. * Various small fixes on the metametrics branch. * Add origin custom variable type to metametrics.util * Fix names of onboarding complete actions (metametrics). * Fix names of Metrics Options actions (metametrics). * Clean up code related to metametrics. * Fix bad merge conflict resolution and improve promise handling in sendMetaMetrics event and confrim tx base * Don't send a second metrics event if user has gone back during first time flow. * Collect metametrics on going back from onboarding create/import. * Add missing custom variable constants for metametrics * Fix metametrics provider * Make height of opt-in modal responsive. * Adjust text content for opt-in modal. * Update metametrics event names and clean up code in opt-in-modal * Put phishing warning step next to last in onboarding flow * Link terms of service on create and import screens of first time flow * Add subtext to options on the onboarding select action screen. * Fix styling of bullet points on end of onboarding screen. * Combine phishing warning and congratulations screens. * Fix placement of users if unlocking after an incomplete onboarding import flow. * Fix capitalization in opt-in screen * Fix last onboarding screen translations * Add link to 'Learn More' on the last screen of onboarding * Code clean up: metametrics branch * Update e2e tests for phishing warning step removal * e2e tests passing on metametrics branch * Different tracking urls for metametrics on development and prod
2019-03-05 16:45:01 +01:00
metricsEvent: PropTypes.func,
2018-03-31 02:37:24 +02:00
}
module.exports = compose(
withRouter,
connect(mapStateToProps, mapDispatchToProps)
)(Routes)