diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | app/_locales/en/messages.json | 6 | ||||
-rw-r--r-- | app/scripts/inpage.js | 6 | ||||
-rw-r--r-- | app/scripts/lib/auto-reload.js | 61 | ||||
-rw-r--r-- | ui/app/components/dropdowns/token-menu-dropdown.js | 53 | ||||
-rw-r--r-- | ui/app/css/itcss/components/token-list.scss | 6 |
6 files changed, 110 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 40521c569..43302548b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,6 @@ - Fix bug where account reset did not work with custom RPC providers. - Fix for Brave i18n getAcceptLanguages [#4270](https://github.com/MetaMask/metamask-extension/issues/4270) - Fix bug where nonce mutex was never released -- Stop reloading browser page on Ethereum network change - Add phishing notice ## 4.7.4 Tue Jun 05 2018 diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 457c3c3b1..2579da87d 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -146,6 +146,9 @@ "copy": { "message": "Copy" }, + "copyContractAddress": { + "message": "Copy Contract Address" + }, "copyToClipboard": { "message": "Copy to clipboard" }, @@ -955,6 +958,9 @@ "viewAccount": { "message": "View Account" }, + "viewOnEtherscan": { + "message": "View on Etherscan" + }, "visitWebSite": { "message": "Visit our web site" }, diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 070f5d247..7dd7fda02 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -3,6 +3,7 @@ cleanContextForImports() require('web3/dist/web3.min.js') const log = require('loglevel') const LocalMessageDuplexStream = require('post-message-stream') +const setupDappAutoReload = require('./lib/auto-reload.js') const MetamaskInpageProvider = require('./lib/inpage-provider.js') restoreContextAfterImports() @@ -38,7 +39,11 @@ web3.setProvider = function () { } log.debug('MetaMask - injected web3') +setupDappAutoReload(web3, inpageProvider.publicConfigStore) + // export global web3, with usage-detection and deprecation warning + +/* TODO: Uncomment this area once auto-reload.js has been deprecated: let hasBeenWarned = false global.web3 = new Proxy(web3, { get: (_web3, key) => { @@ -55,6 +60,7 @@ global.web3 = new Proxy(web3, { _web3[key] = value }, }) +*/ // set web3 defaultAccount inpageProvider.publicConfigStore.subscribe(function (state) { diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js new file mode 100644 index 000000000..cce31c3d2 --- /dev/null +++ b/app/scripts/lib/auto-reload.js @@ -0,0 +1,61 @@ +module.exports = setupDappAutoReload + +function setupDappAutoReload (web3, observable) { + // export web3 as a global, checking for usage + let hasBeenWarned = false + let reloadInProgress = false + let lastTimeUsed + let lastSeenNetwork + + global.web3 = new Proxy(web3, { + get: (_web3, key) => { + // show warning once on web3 access + if (!hasBeenWarned && key !== 'currentProvider') { + console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation') + hasBeenWarned = true + } + // get the time of use + lastTimeUsed = Date.now() + // return value normally + return _web3[key] + }, + set: (_web3, key, value) => { + // set value normally + _web3[key] = value + }, + }) + + observable.subscribe(function (state) { + // if reload in progress, no need to check reload logic + if (reloadInProgress) return + + const currentNetwork = state.networkVersion + + // set the initial network + if (!lastSeenNetwork) { + lastSeenNetwork = currentNetwork + return + } + + // skip reload logic if web3 not used + if (!lastTimeUsed) return + + // if network did not change, exit + if (currentNetwork === lastSeenNetwork) return + + // initiate page reload + reloadInProgress = true + const timeSinceUse = Date.now() - lastTimeUsed + // if web3 was recently used then delay the reloading of the page + if (timeSinceUse > 500) { + triggerReset() + } else { + setTimeout(triggerReset, 500) + } + }) +} + +// reload the page +function triggerReset () { + global.location.reload() +} diff --git a/ui/app/components/dropdowns/token-menu-dropdown.js b/ui/app/components/dropdowns/token-menu-dropdown.js index b70d0b893..fac7c451b 100644 --- a/ui/app/components/dropdowns/token-menu-dropdown.js +++ b/ui/app/components/dropdowns/token-menu-dropdown.js @@ -4,14 +4,21 @@ const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') - +const genAccountLink = require('etherscan-link').createAccountLink +const copyToClipboard = require('copy-to-clipboard') +const { Menu, Item, CloseArea } = require('./components/menu') TokenMenuDropdown.contextTypes = { t: PropTypes.func, } -module.exports = connect(null, mapDispatchToProps)(TokenMenuDropdown) +module.exports = connect(mapStateToProps, mapDispatchToProps)(TokenMenuDropdown) +function mapStateToProps (state) { + return { + network: state.metamask.network, + } +} function mapDispatchToProps (dispatch) { return { @@ -37,22 +44,34 @@ TokenMenuDropdown.prototype.onClose = function (e) { TokenMenuDropdown.prototype.render = function () { const { showHideTokenConfirmationModal } = this.props - return h('div.token-menu-dropdown', {}, [ - h('div.token-menu-dropdown__close-area', { + return h(Menu, { className: 'token-menu-dropdown', isShowing: true }, [ + h(CloseArea, { onClick: this.onClose, }), - h('div.token-menu-dropdown__container', {}, [ - h('div.token-menu-dropdown__options', {}, [ - - h('div.token-menu-dropdown__option', { - onClick: (e) => { - e.stopPropagation() - showHideTokenConfirmationModal(this.props.token) - this.props.onClose() - }, - }, this.context.t('hideToken')), - - ]), - ]), + h(Item, { + onClick: (e) => { + e.stopPropagation() + showHideTokenConfirmationModal(this.props.token) + this.props.onClose() + }, + text: this.context.t('hideToken'), + }), + h(Item, { + onClick: (e) => { + e.stopPropagation() + copyToClipboard(this.props.token.address) + this.props.onClose() + }, + text: this.context.t('copyContractAddress'), + }), + h(Item, { + onClick: (e) => { + e.stopPropagation() + const url = genAccountLink(this.props.token.address, this.props.network) + global.platform.openWindow({ url }) + this.props.onClose() + }, + text: this.context.t('viewOnEtherscan'), + }), ]) } diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index 72fda372f..4b706abce 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -81,13 +81,9 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( } .token-menu-dropdown { - height: 55px; width: 80%; - border-radius: 4px; - background-color: rgba(0, 0, 0, .82); - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5); position: absolute; - top: 60px; + top: 52px; right: 25px; z-index: 2000; |