aboutsummaryrefslogtreecommitdiffstats
path: root/old-ui/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'old-ui/app/components')
-rw-r--r--old-ui/app/components/app-bar.js432
-rw-r--r--old-ui/app/components/qr-code.js79
-rw-r--r--old-ui/app/components/shapeshift-form.js4
3 files changed, 433 insertions, 82 deletions
diff --git a/old-ui/app/components/app-bar.js b/old-ui/app/components/app-bar.js
new file mode 100644
index 000000000..8ab647efd
--- /dev/null
+++ b/old-ui/app/components/app-bar.js
@@ -0,0 +1,432 @@
+const PropTypes = require('prop-types')
+const {Component} = require('react')
+const h = require('react-hyperscript')
+const actions = require('../../../ui/app/actions')
+const SandwichExpando = require('sandwich-expando')
+const {Dropdown} = require('./dropdown')
+const {DropdownMenuItem} = require('./dropdown')
+const NetworkIndicator = require('./network')
+const {AccountDropdowns} = require('./account-dropdowns')
+
+const LOCALHOST_RPC_URL = 'http://localhost:8545'
+
+module.exports = class AppBar extends Component {
+ static defaultProps = {
+ selectedAddress: undefined,
+ }
+
+ static propTypes = {
+ dispatch: PropTypes.func.isRequired,
+ frequentRpcList: PropTypes.array.isRequired,
+ isMascara: PropTypes.bool.isRequired,
+ isOnboarding: PropTypes.bool.isRequired,
+ identities: PropTypes.any.isRequired,
+ selectedAddress: PropTypes.string,
+ isUnlocked: PropTypes.bool.isRequired,
+ network: PropTypes.any.isRequired,
+ keyrings: PropTypes.any.isRequired,
+ provider: PropTypes.any.isRequired,
+ }
+
+ static renderSpace () {
+ return (
+ h('span', {
+ dangerouslySetInnerHTML: {
+ __html: ' ',
+ },
+ })
+ )
+ }
+
+ state = {
+ isNetworkMenuOpen: false,
+ }
+
+ renderAppBar () {
+ if (window.METAMASK_UI_TYPE === 'notification') {
+ return null
+ }
+
+ const props = this.props
+ const {isMascara, isOnboarding} = props
+
+ // Do not render header if user is in mascara onboarding
+ if (isMascara && isOnboarding) {
+ return null
+ }
+
+ // Do not render header if user is in mascara buy ether
+ if (isMascara && props.currentView.name === 'buyEth') {
+ return null
+ }
+
+ return (
+ h('div.app-bar', [
+ this.renderAppBarNewUiNotice(),
+ this.renderAppBarAppHeader(),
+ ])
+ )
+ }
+
+ renderAppBarNewUiNotice () {
+ const {dispatch} = this.props
+
+ return (
+ h('div.app-bar__new-ui-banner', {
+ style: {
+ height: '28px',
+ zIndex: 12,
+ },
+ }, [
+ 'Try the New MetaMask',
+ AppBar.renderSpace(),
+ h('span.banner__link', {
+ async onClick () {
+ await dispatch(actions.setFeatureFlag('betaUI', true))
+ global.platform.openExtensionInBrowser()
+ },
+ }, [
+ 'Now',
+ ]),
+ AppBar.renderSpace(),
+ 'or',
+ AppBar.renderSpace(),
+ h('span.banner__link', {
+ onClick () {
+ global.platform.openWindow({
+ url: 'https://medium.com/metamask/74dba32cc7f7',
+ })
+ },
+ }, [
+ 'Learn More',
+ ]),
+ ])
+ )
+ }
+
+ renderAppBarAppHeader () {
+ const {
+ identities,
+ selectedAddress,
+ isUnlocked,
+ network,
+ keyrings,
+ provider,
+ } = this.props
+ const {
+ isNetworkMenuOpen,
+ isMainMenuOpen,
+ } = this.state
+
+ return (
+ h('.full-width', {
+ style: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '38px',
+ },
+ }, [
+ h('.app-header.flex-row.flex-space-between', {
+ style: {
+ alignItems: 'center',
+ visibility: isUnlocked ? 'visible' : 'none',
+ background: isUnlocked ? 'white' : 'none',
+ height: '38px',
+ position: 'relative',
+ zIndex: 12,
+ },
+ }, [
+ h('div.left-menu-section', {
+ style: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ }, [
+ // mini logo
+ h('img', {
+ height: 24,
+ width: 24,
+ src: './images/icon-128.png',
+ }),
+ h(NetworkIndicator, {
+ network: network,
+ provider: provider,
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
+ },
+ }),
+ ]),
+ isUnlocked && h('div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ }, [
+ h(AccountDropdowns, {
+ style: {},
+ enableAccountsSelector: true,
+ identities: identities,
+ selected: selectedAddress,
+ network,
+ keyrings,
+ }, []),
+ h(SandwichExpando, {
+ className: 'sandwich-expando',
+ width: 16,
+ barHeight: 2,
+ padding: 0,
+ isOpen: isMainMenuOpen,
+ color: 'rgb(247,146,30)',
+ onClick: () => {
+ this.setState({
+ isMainMenuOpen: !isMainMenuOpen,
+ })
+ },
+ }),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ renderNetworkDropdown () {
+ const {
+ dispatch,
+ frequentRpcList: rpcList,
+ provider,
+ } = this.props
+ const {
+ type: providerType,
+ rpcTarget: activeNetwork,
+ } = provider
+ const isOpen = this.state.isNetworkMenuOpen
+
+ return h(Dropdown, {
+ useCssTransition: true,
+ isOpen,
+ onClickOutside: (event) => {
+ const { classList } = event.target
+ const isNotToggleElement = [
+ classList.contains('menu-icon'),
+ classList.contains('network-name'),
+ classList.contains('network-indicator'),
+ ].filter(bool => bool).length === 0
+ // classes from three constituent nodes of the toggle element
+
+ if (isNotToggleElement) {
+ this.setState({ isNetworkMenuOpen: false })
+ }
+ },
+ zIndex: 11,
+ style: {
+ position: 'absolute',
+ left: '2px',
+ top: '64px',
+ },
+ innerStyle: {
+ padding: '2px 16px 2px 0px',
+ },
+ }, [
+ h(DropdownMenuItem, {
+ key: 'main',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => dispatch(actions.setProviderType('mainnet')),
+ style: {
+ fontSize: '18px',
+ },
+ }, [
+ h('.menu-icon.diamond'),
+ 'Main Ethereum Network',
+ providerType === 'mainnet'
+ ? h('.check', '✓')
+ : null,
+ ]),
+ h(DropdownMenuItem, {
+ key: 'ropsten',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => dispatch(actions.setProviderType('ropsten')),
+ style: {
+ fontSize: '18px',
+ },
+ }, [
+ h('.menu-icon.red-dot'),
+ 'Ropsten Test Network',
+ providerType === 'ropsten'
+ ? h('.check', '✓')
+ : null,
+ ]),
+ h(DropdownMenuItem, {
+ key: 'kovan',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => dispatch(actions.setProviderType('kovan')),
+ style: {
+ fontSize: '18px',
+ },
+ }, [
+ h('.menu-icon.hollow-diamond'),
+ 'Kovan Test Network',
+ providerType === 'kovan'
+ ? h('.check', '✓')
+ : null,
+ ]),
+ h(DropdownMenuItem, {
+ key: 'rinkeby',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => dispatch(actions.setProviderType('rinkeby')),
+ style: {
+ fontSize: '18px',
+ },
+ }, [
+ h('.menu-icon.golden-square'),
+ 'Rinkeby Test Network',
+ providerType === 'rinkeby'
+ ? h('.check', '✓')
+ : null,
+ ]),
+ h(DropdownMenuItem, {
+ key: 'default',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => dispatch(actions.setProviderType('localhost')),
+ style: {
+ fontSize: '18px',
+ },
+ }, [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ 'Localhost 8545',
+ activeNetwork === LOCALHOST_RPC_URL
+ ? h('.check', '✓')
+ : null,
+ ]),
+
+ this.renderCustomOption(provider),
+ this.renderCommonRpc(rpcList, provider),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => dispatch(actions.showConfigPage()),
+ style: {
+ fontSize: '18px',
+ },
+ }, [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ 'Custom RPC',
+ activeNetwork === 'custom'
+ ? h('.check', '✓')
+ : null,
+ ]),
+ ])
+ }
+
+ renderCustomOption ({ rpcTarget, type }) {
+ const {dispatch} = this.props
+
+ if (type !== 'rpc') {
+ return null
+ }
+
+ // Concatenate long URLs
+ let label = rpcTarget
+ if (rpcTarget.length > 31) {
+ label = label.substr(0, 34) + '...'
+ }
+
+ switch (rpcTarget) {
+ case LOCALHOST_RPC_URL:
+ return null
+ default:
+ return h(DropdownMenuItem, {
+ key: rpcTarget,
+ onClick: () => dispatch(actions.setRpcTarget(rpcTarget)),
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ }, [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ label,
+ h('.check', '✓'),
+ ])
+ }
+ }
+
+ renderCommonRpc (rpcList, {rpcTarget}) {
+ const {dispatch} = this.props
+
+ return rpcList.map((rpc) => {
+ if ((rpc === LOCALHOST_RPC_URL) || (rpc === rpcTarget)) {
+ return null
+ } else {
+ return h(DropdownMenuItem, {
+ key: `common${rpc}`,
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ onClick: () => dispatch(actions.setRpcTarget(rpc)),
+ }, [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ rpc,
+ rpcTarget === rpc
+ ? h('.check', '✓')
+ : null,
+ ])
+ }
+ })
+ }
+
+ renderDropdown () {
+ const {dispatch} = this.props
+ const isOpen = this.state.isMainMenuOpen
+
+ return h(Dropdown, {
+ useCssTransition: true,
+ isOpen: isOpen,
+ zIndex: 11,
+ onClickOutside: (event) => {
+ const classList = event.target.classList
+ const parentClassList = event.target.parentElement.classList
+
+ const isToggleElement = classList.contains('sandwich-expando') ||
+ parentClassList.contains('sandwich-expando')
+
+ if (isOpen && !isToggleElement) {
+ this.setState({ isMainMenuOpen: false })
+ }
+ },
+ style: {
+ position: 'absolute',
+ right: '2px',
+ top: '66px',
+ },
+ innerStyle: {},
+ }, [
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => { dispatch(actions.showConfigPage()) },
+ }, 'Settings'),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => { dispatch(actions.lockMetamask()) },
+ }, 'Log Out'),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => { dispatch(actions.showInfoPage()) },
+ }, 'Info/Help'),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => {
+ dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
+ },
+ }, 'Try Beta!'),
+ ])
+ }
+
+ render () {
+ return h('div.full-width', [
+ this.renderAppBar(),
+ this.renderNetworkDropdown(),
+ this.renderDropdown(),
+ ])
+ }
+}
diff --git a/old-ui/app/components/qr-code.js b/old-ui/app/components/qr-code.js
deleted file mode 100644
index 06b9aed9b..000000000
--- a/old-ui/app/components/qr-code.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const qrCode = require('qrcode-npm').qrcode
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const isHexPrefixed = require('ethereumjs-util').isHexPrefixed
-const CopyButton = require('./copyButton')
-
-module.exports = connect(mapStateToProps)(QrCodeView)
-
-function mapStateToProps (state) {
- return {
- Qr: state.appState.Qr,
- buyView: state.appState.buyView,
- warning: state.appState.warning,
- }
-}
-
-inherits(QrCodeView, Component)
-
-function QrCodeView () {
- Component.call(this)
-}
-
-QrCodeView.prototype.render = function () {
- const props = this.props
- const Qr = props.Qr
- const address = `${isHexPrefixed(Qr.data) ? 'ethereum:' : ''}${Qr.data}`
- const qrImage = qrCode(4, 'M')
- qrImage.addData(address)
- qrImage.make()
- return h('.main-container.flex-column', {
- key: 'qr',
- style: {
- justifyContent: 'center',
- paddingBottom: '45px',
- paddingLeft: '45px',
- paddingRight: '45px',
- alignItems: 'center',
- },
- }, [
- Array.isArray(Qr.message) ? h('.message-container', this.renderMultiMessage()) : h('.qr-header', Qr.message),
-
- this.props.warning ? this.props.warning && h('span.error.flex-center', {
- style: {
- textAlign: 'center',
- width: '229px',
- height: '82px',
- },
- },
- this.props.warning) : null,
-
- h('#qr-container.flex-column', {
- style: {
- marginTop: '25px',
- marginBottom: '15px',
- },
- dangerouslySetInnerHTML: {
- __html: qrImage.createTableTag(4),
- },
- }),
- h('.flex-row', [
- h('h3.ellip-address', {
- style: {
- width: '247px',
- },
- }, Qr.data),
- h(CopyButton, {
- value: Qr.data,
- }),
- ]),
- ])
-}
-
-QrCodeView.prototype.renderMultiMessage = function () {
- var Qr = this.props.Qr
- var multiMessage = Qr.message.map((message) => h('.qr-message', message))
- return multiMessage
-}
diff --git a/old-ui/app/components/shapeshift-form.js b/old-ui/app/components/shapeshift-form.js
index 97068db0a..14de309ab 100644
--- a/old-ui/app/components/shapeshift-form.js
+++ b/old-ui/app/components/shapeshift-form.js
@@ -3,7 +3,6 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const actions = require('../../../ui/app/actions')
-const Qr = require('./qr-code')
const isValidAddress = require('../util').isValidAddress
module.exports = connect(mapStateToProps)(ShapeshiftForm)
@@ -11,7 +10,6 @@ function mapStateToProps (state) {
return {
warning: state.appState.warning,
isSubLoading: state.appState.isSubLoading,
- qrRequested: state.appState.qrRequested,
}
}
@@ -23,7 +21,7 @@ function ShapeshiftForm () {
}
ShapeshiftForm.prototype.render = function () {
- return this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain()
+ return this.renderMain()
}
ShapeshiftForm.prototype.renderMain = function () {