2017-10-13 08:10:58 +02:00
|
|
|
const inherits = require('util').inherits
|
|
|
|
const Component = require('react').Component
|
2018-03-29 17:00:44 +02:00
|
|
|
const connect = require('react-redux').connect
|
2017-11-29 05:24:35 +01:00
|
|
|
const { compose } = require('recompose')
|
|
|
|
const { withRouter } = require('react-router-dom')
|
2018-03-31 01:18:48 +02:00
|
|
|
const PropTypes = require('prop-types')
|
2017-10-13 08:10:58 +02:00
|
|
|
const h = require('react-hyperscript')
|
|
|
|
const actions = require('../../actions')
|
2017-10-16 07:28:25 +02:00
|
|
|
const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu')
|
2018-07-02 21:14:57 +02:00
|
|
|
const { ENVIRONMENT_TYPE_POPUP } = require('../../../../app/scripts/lib/enums')
|
|
|
|
const { getEnvironmentType } = require('../../../../app/scripts/lib/util')
|
2018-07-12 06:23:08 +02:00
|
|
|
const Tooltip = require('../tooltip')
|
2018-10-25 11:21:41 +02:00
|
|
|
import Identicon from '../identicon'
|
2018-10-17 01:03:29 +02:00
|
|
|
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'
|
|
|
|
import { PRIMARY } from '../../constants/common'
|
2018-11-30 23:51:24 +01:00
|
|
|
import { getMetaMaskAccounts } from '../../selectors'
|
2018-07-02 21:14:57 +02:00
|
|
|
|
2018-02-01 03:08:49 +01:00
|
|
|
const {
|
|
|
|
SETTINGS_ROUTE,
|
|
|
|
INFO_ROUTE,
|
|
|
|
NEW_ACCOUNT_ROUTE,
|
|
|
|
IMPORT_ACCOUNT_ROUTE,
|
2018-06-10 09:52:32 +02:00
|
|
|
CONNECT_HARDWARE_ROUTE,
|
2018-02-01 03:08:49 +01:00
|
|
|
DEFAULT_ROUTE,
|
|
|
|
} = require('../../routes')
|
2017-10-13 08:10:58 +02:00
|
|
|
|
2017-11-29 05:24:35 +01:00
|
|
|
module.exports = compose(
|
|
|
|
withRouter,
|
|
|
|
connect(mapStateToProps, mapDispatchToProps)
|
|
|
|
)(AccountMenu)
|
2017-10-13 08:10:58 +02:00
|
|
|
|
2018-03-29 17:00:44 +02:00
|
|
|
AccountMenu.contextTypes = {
|
|
|
|
t: PropTypes.func,
|
|
|
|
}
|
|
|
|
|
2017-10-13 08:10:58 +02:00
|
|
|
inherits(AccountMenu, Component)
|
|
|
|
function AccountMenu () { Component.call(this) }
|
|
|
|
|
|
|
|
function mapStateToProps (state) {
|
|
|
|
return {
|
|
|
|
selectedAddress: state.metamask.selectedAddress,
|
2017-10-16 07:28:25 +02:00
|
|
|
isAccountMenuOpen: state.metamask.isAccountMenuOpen,
|
|
|
|
keyrings: state.metamask.keyrings,
|
|
|
|
identities: state.metamask.identities,
|
2018-11-30 23:51:24 +01:00
|
|
|
accounts: getMetaMaskAccounts(state),
|
2017-10-13 08:10:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-16 07:28:25 +02:00
|
|
|
function mapDispatchToProps (dispatch) {
|
|
|
|
return {
|
|
|
|
toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
|
2017-10-18 07:36:53 +02:00
|
|
|
showAccountDetail: address => {
|
|
|
|
dispatch(actions.showAccountDetail(address))
|
2017-12-20 18:49:13 +01:00
|
|
|
dispatch(actions.hideSidebar())
|
2017-10-18 07:36:53 +02:00
|
|
|
dispatch(actions.toggleAccountMenu())
|
|
|
|
},
|
|
|
|
lockMetamask: () => {
|
|
|
|
dispatch(actions.lockMetamask())
|
2018-01-12 00:49:10 +01:00
|
|
|
dispatch(actions.hideWarning())
|
2017-12-20 18:49:13 +01:00
|
|
|
dispatch(actions.hideSidebar())
|
2017-10-18 07:36:53 +02:00
|
|
|
dispatch(actions.toggleAccountMenu())
|
|
|
|
},
|
|
|
|
showConfigPage: () => {
|
|
|
|
dispatch(actions.showConfigPage())
|
2017-12-20 18:49:13 +01:00
|
|
|
dispatch(actions.hideSidebar())
|
2017-10-18 07:36:53 +02:00
|
|
|
dispatch(actions.toggleAccountMenu())
|
|
|
|
},
|
2017-10-25 18:26:05 +02:00
|
|
|
showInfoPage: () => {
|
|
|
|
dispatch(actions.showInfoPage())
|
2017-12-20 18:49:13 +01:00
|
|
|
dispatch(actions.hideSidebar())
|
2017-10-18 07:36:53 +02:00
|
|
|
dispatch(actions.toggleAccountMenu())
|
|
|
|
},
|
2018-07-12 19:19:51 +02:00
|
|
|
showRemoveAccountConfirmationModal: (identity) => {
|
|
|
|
return dispatch(actions.showModal({ name: 'CONFIRM_REMOVE_ACCOUNT', identity }))
|
2018-07-11 01:19:29 +02:00
|
|
|
},
|
2017-10-16 07:28:25 +02:00
|
|
|
}
|
2017-10-13 08:10:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
AccountMenu.prototype.render = function () {
|
2017-10-18 07:36:53 +02:00
|
|
|
const {
|
|
|
|
isAccountMenuOpen,
|
|
|
|
toggleAccountMenu,
|
|
|
|
lockMetamask,
|
2017-11-29 05:24:35 +01:00
|
|
|
history,
|
2017-10-18 07:36:53 +02:00
|
|
|
} = this.props
|
|
|
|
|
2017-10-16 07:28:25 +02:00
|
|
|
return h(Menu, { className: 'account-menu', isShowing: isAccountMenuOpen }, [
|
|
|
|
h(CloseArea, { onClick: toggleAccountMenu }),
|
2017-10-18 07:36:53 +02:00
|
|
|
h(Item, {
|
|
|
|
className: 'account-menu__header',
|
|
|
|
}, [
|
2018-03-29 17:00:44 +02:00
|
|
|
this.context.t('myAccounts'),
|
2017-10-24 09:16:19 +02:00
|
|
|
h('button.account-menu__logout-button', {
|
2017-12-04 07:24:30 +01:00
|
|
|
onClick: () => {
|
|
|
|
lockMetamask()
|
|
|
|
history.push(DEFAULT_ROUTE)
|
|
|
|
},
|
2018-03-29 17:00:44 +02:00
|
|
|
}, this.context.t('logout')),
|
2017-10-13 08:10:58 +02:00
|
|
|
]),
|
|
|
|
h(Divider),
|
2017-10-16 07:28:25 +02:00
|
|
|
h('div.account-menu__accounts', this.renderAccounts()),
|
2017-10-13 08:10:58 +02:00
|
|
|
h(Divider),
|
|
|
|
h(Item, {
|
2018-02-01 03:08:49 +01:00
|
|
|
onClick: () => {
|
|
|
|
toggleAccountMenu()
|
|
|
|
history.push(NEW_ACCOUNT_ROUTE)
|
|
|
|
},
|
2018-02-08 03:46:27 +01:00
|
|
|
icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }),
|
2018-03-29 17:00:44 +02:00
|
|
|
text: this.context.t('createAccount'),
|
2017-10-13 08:10:58 +02:00
|
|
|
}),
|
|
|
|
h(Item, {
|
2018-02-01 03:08:49 +01:00
|
|
|
onClick: () => {
|
|
|
|
toggleAccountMenu()
|
|
|
|
history.push(IMPORT_ACCOUNT_ROUTE)
|
|
|
|
},
|
2018-02-08 03:46:27 +01:00
|
|
|
icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }),
|
2018-03-29 17:00:44 +02:00
|
|
|
text: this.context.t('importAccount'),
|
2017-10-13 08:10:58 +02:00
|
|
|
}),
|
2018-06-10 09:52:32 +02:00
|
|
|
h(Item, {
|
|
|
|
onClick: () => {
|
|
|
|
toggleAccountMenu()
|
2018-07-02 21:14:57 +02:00
|
|
|
if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) {
|
|
|
|
global.platform.openExtensionInBrowser(CONNECT_HARDWARE_ROUTE)
|
|
|
|
} else {
|
|
|
|
history.push(CONNECT_HARDWARE_ROUTE)
|
|
|
|
}
|
2018-06-10 09:52:32 +02:00
|
|
|
},
|
|
|
|
icon: h('img.account-menu__item-icon', { src: 'images/connect-icon.svg' }),
|
2018-07-19 04:57:47 +02:00
|
|
|
text: this.context.t('connectHardwareWallet'),
|
2018-06-10 09:52:32 +02:00
|
|
|
}),
|
2017-10-13 08:10:58 +02:00
|
|
|
h(Divider),
|
|
|
|
h(Item, {
|
2017-11-29 05:24:35 +01:00
|
|
|
onClick: () => {
|
|
|
|
toggleAccountMenu()
|
|
|
|
history.push(INFO_ROUTE)
|
|
|
|
},
|
2017-10-13 08:10:58 +02:00
|
|
|
icon: h('img', { src: 'images/mm-info-icon.svg' }),
|
2018-03-29 17:00:44 +02:00
|
|
|
text: this.context.t('infoHelp'),
|
2017-10-13 08:10:58 +02:00
|
|
|
}),
|
|
|
|
h(Item, {
|
2017-11-29 05:24:35 +01:00
|
|
|
onClick: () => {
|
|
|
|
toggleAccountMenu()
|
|
|
|
history.push(SETTINGS_ROUTE)
|
|
|
|
},
|
2018-02-08 03:46:27 +01:00
|
|
|
icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }),
|
2018-03-29 17:00:44 +02:00
|
|
|
text: this.context.t('settings'),
|
2017-10-13 08:10:58 +02:00
|
|
|
}),
|
|
|
|
])
|
|
|
|
}
|
|
|
|
|
2017-10-16 07:28:25 +02:00
|
|
|
AccountMenu.prototype.renderAccounts = function () {
|
2017-10-18 07:36:53 +02:00
|
|
|
const {
|
|
|
|
identities,
|
|
|
|
accounts,
|
2017-10-24 09:13:49 +02:00
|
|
|
selectedAddress,
|
2017-10-18 07:36:53 +02:00
|
|
|
keyrings,
|
|
|
|
showAccountDetail,
|
|
|
|
} = this.props
|
2017-10-16 07:28:25 +02:00
|
|
|
|
2018-06-05 00:03:03 +02:00
|
|
|
const accountOrder = keyrings.reduce((list, keyring) => list.concat(keyring.accounts), [])
|
2018-07-11 06:20:40 +02:00
|
|
|
return accountOrder.filter(address => !!identities[address]).map((address) => {
|
|
|
|
|
2018-06-05 00:03:03 +02:00
|
|
|
const identity = identities[address]
|
2017-10-24 09:13:49 +02:00
|
|
|
const isSelected = identity.address === selectedAddress
|
2017-10-16 07:28:25 +02:00
|
|
|
|
2018-06-05 00:03:03 +02:00
|
|
|
const balanceValue = accounts[address] ? accounts[address].balance : ''
|
2017-10-16 07:28:25 +02:00
|
|
|
const simpleAddress = identity.address.substring(2).toLowerCase()
|
|
|
|
|
|
|
|
const keyring = keyrings.find((kr) => {
|
|
|
|
return kr.accounts.includes(simpleAddress) ||
|
|
|
|
kr.accounts.includes(identity.address)
|
|
|
|
})
|
|
|
|
|
|
|
|
return h(
|
2017-10-18 07:36:53 +02:00
|
|
|
'div.account-menu__account.menu__item--clickable',
|
|
|
|
{ onClick: () => showAccountDetail(identity.address) },
|
2017-10-16 07:28:25 +02:00
|
|
|
[
|
|
|
|
h('div.account-menu__check-mark', [
|
2017-10-24 09:13:49 +02:00
|
|
|
isSelected ? h('div.account-menu__check-mark-icon') : null,
|
2017-10-16 07:28:25 +02:00
|
|
|
]),
|
2017-10-13 08:10:58 +02:00
|
|
|
|
2017-10-16 07:28:25 +02:00
|
|
|
h(
|
|
|
|
Identicon,
|
|
|
|
{
|
|
|
|
address: identity.address,
|
|
|
|
diameter: 24,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
|
|
|
|
h('div.account-menu__account-info', [
|
2017-10-18 07:36:53 +02:00
|
|
|
h('div.account-menu__name', identity.name || ''),
|
2018-10-17 01:03:29 +02:00
|
|
|
h(UserPreferencedCurrencyDisplay, {
|
|
|
|
className: 'account-menu__balance',
|
|
|
|
value: balanceValue,
|
|
|
|
type: PRIMARY,
|
|
|
|
}),
|
2017-10-16 07:28:25 +02:00
|
|
|
]),
|
|
|
|
|
2018-07-10 06:20:00 +02:00
|
|
|
this.renderKeyringType(keyring),
|
2018-07-12 19:19:51 +02:00
|
|
|
this.renderRemoveAccount(keyring, identity),
|
2017-10-16 07:28:25 +02:00
|
|
|
],
|
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-07-12 19:19:51 +02:00
|
|
|
AccountMenu.prototype.renderRemoveAccount = function (keyring, identity) {
|
2018-07-11 07:35:37 +02:00
|
|
|
// Any account that's not from the HD wallet Keyring can be removed
|
2018-07-10 06:20:00 +02:00
|
|
|
const type = keyring.type
|
2018-07-11 06:20:40 +02:00
|
|
|
const isRemovable = type !== 'HD Key Tree'
|
2018-07-12 06:23:08 +02:00
|
|
|
if (isRemovable) {
|
|
|
|
return h(Tooltip, {
|
|
|
|
title: this.context.t('removeAccount'),
|
|
|
|
position: 'bottom',
|
|
|
|
}, [
|
|
|
|
h('a.remove-account-icon', {
|
2018-07-12 19:19:51 +02:00
|
|
|
onClick: (e) => this.removeAccount(e, identity),
|
2018-07-12 06:23:08 +02:00
|
|
|
}, ''),
|
|
|
|
])
|
|
|
|
}
|
|
|
|
return null
|
2018-07-10 06:20:00 +02:00
|
|
|
}
|
|
|
|
|
2018-07-12 19:19:51 +02:00
|
|
|
AccountMenu.prototype.removeAccount = function (e, identity) {
|
2018-07-10 06:20:00 +02:00
|
|
|
e.preventDefault()
|
|
|
|
e.stopPropagation()
|
2018-07-11 06:20:40 +02:00
|
|
|
const { showRemoveAccountConfirmationModal } = this.props
|
2018-07-12 19:19:51 +02:00
|
|
|
showRemoveAccountConfirmationModal(identity)
|
2018-07-10 06:20:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
AccountMenu.prototype.renderKeyringType = function (keyring) {
|
2017-10-16 07:28:25 +02:00
|
|
|
try { // Sometimes keyrings aren't loaded yet:
|
|
|
|
const type = keyring.type
|
2018-07-10 06:20:00 +02:00
|
|
|
let label
|
|
|
|
switch (type) {
|
|
|
|
case 'Trezor Hardware':
|
2018-08-11 11:11:21 +02:00
|
|
|
case 'Ledger Hardware':
|
2018-07-10 06:20:00 +02:00
|
|
|
label = this.context.t('hardware')
|
|
|
|
break
|
|
|
|
case 'Simple Key Pair':
|
|
|
|
label = this.context.t('imported')
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
label = ''
|
|
|
|
}
|
|
|
|
|
|
|
|
return label !== '' ? h('.keyring-label.allcaps', label) : null
|
|
|
|
|
2017-10-16 07:28:25 +02:00
|
|
|
} catch (e) { return }
|
|
|
|
}
|