Refactor notification manager and triggerUi to use extension platform (#8317)

The notification manager has been refactored to use the extension
platform module instead of using `extensionizer` directly. The
extension platform API presents a more ergonomic API, and it correctly
handles errors (which the old notification manager did not). Methods
that the extension platform lacked have been added.

It has been updated to use `async/await` instead of callbacks as well,
for readability.

The `triggerUI` function has also been updated to use the extension
platform instead of `extensionizer`.
feature/default_network_editable
Mark Stacey 5 years ago committed by GitHub
parent e60cac8535
commit 852277b2ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      app/scripts/background.js
  2. 100
      app/scripts/lib/notification-manager.js
  3. 60
      app/scripts/platforms/extension.js

@ -455,22 +455,21 @@ function setupController (initState, initLangCode) {
/** /**
* Opens the browser popup for user confirmation * Opens the browser popup for user confirmation
*/ */
function triggerUi () { async function triggerUi () {
extension.tabs.query({ active: true }, (tabs) => { const tabs = await platform.getActiveTabs()
const currentlyActiveMetamaskTab = Boolean(tabs.find((tab) => openMetamaskTabsIDs[tab.id])) const currentlyActiveMetamaskTab = Boolean(tabs.find((tab) => openMetamaskTabsIDs[tab.id]))
if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) { if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) {
notificationManager.showPopup() await notificationManager.showPopup()
} }
})
} }
/** /**
* Opens the browser popup for user confirmation of watchAsset * Opens the browser popup for user confirmation of watchAsset
* then it waits until user interact with the UI * then it waits until user interact with the UI
*/ */
function openPopup () { async function openPopup () {
triggerUi() await triggerUi()
return new Promise( await new Promise(
(resolve) => { (resolve) => {
const interval = setInterval(() => { const interval = setInterval(() => {
if (!notificationIsOpen) { if (!notificationIsOpen) {

@ -1,4 +1,4 @@
import extension from 'extensionizer' import ExtensionPlatform from '../platforms/extension'
const NOTIFICATION_HEIGHT = 620 const NOTIFICATION_HEIGHT = 620
const NOTIFICATION_WIDTH = 360 const NOTIFICATION_WIDTH = 360
@ -12,57 +12,49 @@ class NotificationManager {
* *
*/ */
constructor () {
this.platform = new ExtensionPlatform()
}
/** /**
* Either brings an existing MetaMask notification window into focus, or creates a new notification window. New * Either brings an existing MetaMask notification window into focus, or creates a new notification window. New
* notification windows are given a 'popup' type. * notification windows are given a 'popup' type.
* *
*/ */
showPopup () { async showPopup () {
this._getPopup((err, popup) => { const popup = await this._getPopup()
if (err) {
throw err
}
// Bring focus to chrome popup // Bring focus to chrome popup
if (popup) { if (popup) {
// bring focus to existing chrome popup // bring focus to existing chrome popup
extension.windows.update(popup.id, { focused: true }) await this.platform.focusWindow(popup.id)
} else { } else {
const { screenX, screenY, outerWidth, outerHeight } = window const { screenX, screenY, outerWidth, outerHeight } = window
const notificationTop = Math.round(screenY + (outerHeight / 2) - (NOTIFICATION_HEIGHT / 2)) const notificationTop = Math.round(screenY + (outerHeight / 2) - (NOTIFICATION_HEIGHT / 2))
const notificationLeft = Math.round(screenX + (outerWidth / 2) - (NOTIFICATION_WIDTH / 2)) const notificationLeft = Math.round(screenX + (outerWidth / 2) - (NOTIFICATION_WIDTH / 2))
const cb = (currentPopup) => { // create new notification popup
this._popupId = currentPopup.id const popupWindow = await this.platform.openWindow({
} url: 'notification.html',
// create new notification popup type: 'popup',
const creation = extension.windows.create({ width: NOTIFICATION_WIDTH,
url: 'notification.html', height: NOTIFICATION_HEIGHT,
type: 'popup', top: Math.max(notificationTop, 0),
width: NOTIFICATION_WIDTH, left: Math.max(notificationLeft, 0),
height: NOTIFICATION_HEIGHT, })
top: Math.max(notificationTop, 0), this._popupId = popupWindow.id
left: Math.max(notificationLeft, 0), }
}, cb)
creation && creation.then && creation.then(cb)
}
})
} }
/** /**
* Closes a MetaMask notification if it window exists. * Closes a MetaMask notification if it window exists.
* *
*/ */
closePopup () { async closePopup () {
// closes notification popup const popup = this._getPopup()
this._getPopup((err, popup) => { if (!popup) {
if (err) { return
throw err }
} await this.platform.removeWindow(popup.id)
if (!popup) {
return
}
extension.windows.remove(popup.id, console.error)
})
} }
/** /**
@ -73,31 +65,9 @@ class NotificationManager {
* @param {Function} cb - A node style callback that to whcih the found notification window will be passed. * @param {Function} cb - A node style callback that to whcih the found notification window will be passed.
* *
*/ */
_getPopup (cb) { async _getPopup () {
this._getWindows((err, windows) => { const windows = await this.platform.getAllWindows()
if (err) { return this._getPopupIn(windows)
throw err
}
cb(null, this._getPopupIn(windows))
})
}
/**
* Returns all open MetaMask windows.
*
* @private
* @param {Function} cb - A node style callback that to which the windows will be passed.
*
*/
_getWindows (cb) {
// Ignore in test environment
if (!extension.windows) {
return cb()
}
extension.windows.getAll({}, (windows) => {
cb(null, windows)
})
} }
/** /**

@ -12,8 +12,40 @@ class ExtensionPlatform {
extension.runtime.reload() extension.runtime.reload()
} }
openWindow ({ url }) { openWindow (options) {
extension.tabs.create({ url }) return new Promise((resolve, reject) => {
extension.windows.create(options, (newWindow) => {
const error = checkForError()
if (error) {
return reject(error)
}
return resolve(newWindow)
})
})
}
closeWindow (windowId) {
return new Promise((resolve, reject) => {
extension.windows.remove(windowId, () => {
const error = checkForError()
if (error) {
return reject(error)
}
return resolve()
})
})
}
focusWindow (windowId) {
return new Promise((resolve, reject) => {
extension.windows.update(windowId, { focused: true }, () => {
const error = checkForError()
if (error) {
return reject(error)
}
return resolve()
})
})
} }
closeCurrentWindow () { closeCurrentWindow () {
@ -65,6 +97,30 @@ class ExtensionPlatform {
} }
} }
getAllWindows () {
return new Promise((resolve, reject) => {
extension.windows.getAll((windows) => {
const error = checkForError()
if (error) {
return reject(error)
}
return resolve(windows)
})
})
}
getActiveTabs () {
return new Promise((resolve, reject) => {
extension.tabs.query({ active: true }, (tabs) => {
const error = checkForError()
if (error) {
return reject(error)
}
return resolve(tabs)
})
})
}
currentTab () { currentTab () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
extension.tabs.getCurrent((tab) => { extension.tabs.getCurrent((tab) => {

Loading…
Cancel
Save