1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-30 08:09:15 +01:00
metamask-extension/ui/app/app.js

383 lines
12 KiB
JavaScript
Raw Normal View History

const { Component } = require('react')
2017-12-04 09:06:09 +01:00
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const { Route, Switch, withRouter } = require('react-router-dom')
const { compose } = require('recompose')
const h = require('react-hyperscript')
const actions = require('./actions')
2018-01-10 01:45:39 +01:00
const classnames = require('classnames')
const log = require('loglevel')
const { getMetaMaskAccounts, getNetworkIdentifier } = require('./selectors')
2018-01-10 01:45:39 +01:00
// init
const InitializeScreen = require('../../mascara/src/app/first-time').default
// accounts
const SendTransactionScreen = require('./components/send/send.container')
const ConfirmTransaction = require('./components/pages/confirm-transaction')
// slideout menu
const Sidebar = require('./components/sidebars').default
// other views
import Home from './components/pages/home'
import Settings from './components/pages/settings'
const Authenticated = require('./components/pages/authenticated')
const Initialized = require('./components/pages/initialized')
2018-07-05 19:09:55 +02:00
const RestoreVaultPage = require('./components/pages/keychains/restore-vault').default
const RevealSeedConfirmation = require('./components/pages/keychains/reveal-seed')
const AddTokenPage = require('./components/pages/add-token')
2018-05-20 08:04:19 +02:00
const ConfirmAddTokenPage = require('./components/pages/confirm-add-token')
const ConfirmAddSuggestedTokenPage = require('./components/pages/confirm-add-suggested-token')
const CreateAccountPage = require('./components/pages/create-account')
const NoticeScreen = require('./components/pages/notice')
const Loading = require('./components/loading-screen')
const LoadingNetwork = require('./components/loading-network-screen').default
const NetworkDropdown = require('./components/dropdowns/network-dropdown')
2018-12-20 21:26:11 +01:00
import AccountMenu from './components/account-menu'
// Global Modals
const Modal = require('./components/modals/index').Modal
2018-07-19 08:31:02 +02:00
// Global Alert
const Alert = require('./components/alert')
2018-08-19 03:41:19 +02:00
import AppHeader from './components/app-header'
import UnlockPage from './components/pages/unlock-page'
import {
submittedPendingTransactionsSelector,
} from './selectors/transactions'
// Routes
const {
DEFAULT_ROUTE,
UNLOCK_ROUTE,
SETTINGS_ROUTE,
REVEAL_SEED_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,
NOTICE_ROUTE,
} = require('./routes')
class App extends Component {
componentWillMount () {
const { currentCurrency, setCurrentCurrencyToUSD } = this.props
if (!currentCurrency) {
setCurrentCurrencyToUSD()
}
2017-08-07 04:03:38 +02:00
}
renderRoutes () {
const exact = true
return (
h(Switch, [
2018-04-02 11:59:49 +02:00
h(Route, { path: INITIALIZE_ROUTE, component: InitializeScreen }),
h(Initialized, { path: UNLOCK_ROUTE, exact, component: UnlockPage }),
h(Initialized, { path: RESTORE_VAULT_ROUTE, exact, component: RestoreVaultPage }),
h(Authenticated, { path: REVEAL_SEED_ROUTE, exact, component: RevealSeedConfirmation }),
h(Authenticated, { path: SETTINGS_ROUTE, component: Settings }),
h(Authenticated, { path: NOTICE_ROUTE, exact, component: NoticeScreen }),
h(Authenticated, {
path: `${CONFIRM_TRANSACTION_ROUTE}/:id?`,
component: ConfirmTransaction,
}),
h(Authenticated, { path: SEND_ROUTE, exact, component: SendTransactionScreen }),
h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }),
2018-05-20 08:04:19 +02:00
h(Authenticated, { path: CONFIRM_ADD_TOKEN_ROUTE, exact, component: ConfirmAddTokenPage }),
h(Authenticated, { path: CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE, exact, component: ConfirmAddSuggestedTokenPage }),
h(Authenticated, { path: NEW_ACCOUNT_ROUTE, component: CreateAccountPage }),
h(Authenticated, { path: DEFAULT_ROUTE, exact, component: Home }),
])
)
}
render () {
2017-12-04 09:06:09 +01:00
const {
isLoading,
2018-07-19 08:31:02 +02:00
alertMessage,
2017-12-04 09:06:09 +01:00
loadingMessage,
network,
2018-03-27 09:20:35 +02:00
isMouseUser,
2017-12-04 09:06:09 +01:00
provider,
frequentRpcListDetail,
2017-12-04 09:06:09 +01:00
currentView,
2018-03-27 09:20:35 +02:00
setMouseUserState,
sidebar,
submittedPendingTransactions,
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 || {}
return (
h('.flex-column.full-height', {
2018-03-27 09:20:35 +02:00
className: classnames({ 'mouse-user-styles': isMouseUser }),
style: {
overflowX: 'hidden',
position: 'relative',
alignItems: 'center',
},
2018-03-27 09:20:35 +02:00
tabIndex: '0',
onClick: () => setMouseUserState(true),
onKeyDown: (e) => {
if (e.keyCode === 9) {
setMouseUserState(false)
}
},
}, [
2017-08-08 22:37:41 +02:00
// global modal
h(Modal, {}, []),
2018-07-19 08:31:02 +02:00
// global alert
h(Alert, {visible: this.props.alertOpen, msg: alertMessage}),
h(AppHeader),
// sidebar
h(Sidebar, {
sidebarOpen: sidebarIsOpen,
sidebarShouldClose: sidebarTransaction && !submittedPendingTransactions.find(({ id }) => id === sidebarTransaction.id),
hideSidebar: this.props.hideSidebar,
transitionName: sidebarTransitionName,
type: sidebarType,
sidebarProps: sidebar.props,
}),
// network dropdown
h(NetworkDropdown, {
2017-12-04 09:06:09 +01:00
provider,
frequentRpcListDetail,
}, []),
2017-10-13 08:10:58 +02:00
h(AccountMenu),
2017-11-02 13:15:59 +01:00
h('div.main-container-wrapper', [
isLoading && h(Loading, {
loadingMessage: loadMessage,
}),
!isLoading && isLoadingNetwork && h(LoadingNetwork),
// content
this.renderRoutes(),
]),
])
)
}
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.dispatch(actions.lockMetamask(false))
}
}
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')
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 {
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
2017-12-04 09:06:09 +01:00
App.propTypes = {
currentCurrency: PropTypes.string,
setCurrentCurrencyToUSD: PropTypes.func,
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
2018-07-19 08:31:02 +02:00
alertMessage: 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,
isMascara: PropTypes.bool,
isOnboarding: PropTypes.bool,
isUnlocked: PropTypes.bool,
networkDropdownOpen: PropTypes.bool,
showNetworkDropdown: PropTypes.func,
hideNetworkDropdown: PropTypes.func,
history: PropTypes.object,
location: PropTypes.object,
2017-12-04 09:06:09 +01:00
dispatch: PropTypes.func,
toggleAccountMenu: PropTypes.func,
selectedAddress: PropTypes.string,
noActiveNotices: PropTypes.bool,
lostAccounts: PropTypes.array,
isInitialized: PropTypes.bool,
forgottenPassword: PropTypes.bool,
activeAddress: PropTypes.string,
unapprovedTxs: PropTypes.object,
seedWords: PropTypes.string,
submittedPendingTransactions: PropTypes.array,
2017-12-05 04:27:42 +01:00
unapprovedMsgCount: PropTypes.number,
unapprovedPersonalMsgCount: PropTypes.number,
unapprovedTypedMessagesCount: PropTypes.number,
2018-03-27 09:20:35 +02:00
welcomeScreenSeen: PropTypes.bool,
isPopup: PropTypes.bool,
betaUI: PropTypes.bool,
isMouseUser: PropTypes.bool,
setMouseUserState: PropTypes.func,
t: PropTypes.func,
providerId: PropTypes.string,
2017-12-04 09:06:09 +01:00
}
function mapStateToProps (state) {
const { appState, metamask } = state
const {
networkDropdownOpen,
sidebar,
2018-07-19 08:31:02 +02:00
alertOpen,
alertMessage,
isLoading,
loadingMessage,
} = appState
const accounts = getMetaMaskAccounts(state)
const {
identities,
address,
keyrings,
isInitialized,
noActiveNotices,
seedWords,
unapprovedTxs,
nextUnreadNotice,
lostAccounts,
2017-12-05 04:27:42 +01:00
unapprovedMsgCount,
unapprovedPersonalMsgCount,
unapprovedTypedMessagesCount,
} = metamask
const selected = address || Object.keys(accounts)[0]
return {
// state from plugin
networkDropdownOpen,
sidebar,
2018-07-19 08:31:02 +02:00
alertOpen,
alertMessage,
isLoading,
loadingMessage,
noActiveNotices,
isInitialized,
isUnlocked: state.metamask.isUnlocked,
selectedAddress: state.metamask.selectedAddress,
currentView: state.appState.currentView,
activeAddress: state.appState.activeAddress,
transForward: state.appState.transForward,
isMascara: state.metamask.isMascara,
isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
2018-03-27 09:20:35 +02:00
isPopup: state.metamask.isPopup,
seedWords: state.metamask.seedWords,
submittedPendingTransactions: submittedPendingTransactionsSelector(state),
unapprovedTxs,
2018-03-27 09:20:35 +02:00
unapprovedMsgs: state.metamask.unapprovedMsgs,
2017-12-05 04:27:42 +01:00
unapprovedMsgCount,
unapprovedPersonalMsgCount,
unapprovedTypedMessagesCount,
menuOpen: state.appState.menuOpen,
network: state.metamask.network,
provider: state.metamask.provider,
forgottenPassword: state.appState.forgottenPassword,
nextUnreadNotice,
lostAccounts,
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
currentCurrency: state.metamask.currentCurrency,
2018-03-27 09:20:35 +02:00
isMouseUser: state.appState.isMouseUser,
betaUI: state.metamask.featureFlags.betaUI,
isRevealingSeedWords: state.metamask.isRevealingSeedWords,
Qr: state.appState.Qr,
welcomeScreenSeen: state.metamask.welcomeScreenSeen,
providerId: getNetworkIdentifier(state),
// state needed to get account dropdown temporarily rendering from app bar
identities,
selected,
keyrings,
}
}
function mapDispatchToProps (dispatch, ownProps) {
return {
dispatch,
hideSidebar: () => dispatch(actions.hideSidebar()),
showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
2018-03-27 09:20:35 +02:00
setMouseUserState: (isMouseUser) => dispatch(actions.setMouseUserState(isMouseUser)),
}
}
2018-03-31 02:37:24 +02:00
App.contextTypes = {
t: PropTypes.func,
}
module.exports = compose(
withRouter,
connect(mapStateToProps, mapDispatchToProps)
)(App)