mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-12 20:57:12 +01:00
3732c5f71e
ESLint rules have been added to enforce our JSDoc conventions. These rules were introduced by updating `@metamask/eslint-config` to v9. Some of the rules have been disabled because the effort to fix all lint errors was too high. It might be easiest to enable these rules one directory at a time, or one rule at a time. Most of the changes in this PR were a result of running `yarn lint:fix`. There were a handful of manual changes that seemed obvious and simple to make. Anything beyond that and the rule was left disabled.
114 lines
3.5 KiB
JavaScript
114 lines
3.5 KiB
JavaScript
import EventEmitter from 'safe-event-emitter';
|
|
import ExtensionPlatform from '../platforms/extension';
|
|
|
|
const NOTIFICATION_HEIGHT = 620;
|
|
const NOTIFICATION_WIDTH = 360;
|
|
|
|
export const NOTIFICATION_MANAGER_EVENTS = {
|
|
POPUP_CLOSED: 'onPopupClosed',
|
|
};
|
|
|
|
/**
|
|
* A collection of methods for controlling the showing and hiding of the notification popup.
|
|
*/
|
|
export default class NotificationManager extends EventEmitter {
|
|
constructor() {
|
|
super();
|
|
this.platform = new ExtensionPlatform();
|
|
this.platform.addOnRemovedListener(this._onWindowClosed.bind(this));
|
|
}
|
|
|
|
/**
|
|
* Mark the notification popup as having been automatically closed.
|
|
*
|
|
* This lets us differentiate between the cases where we close the
|
|
* notification popup v.s. when the user closes the popup window directly.
|
|
*/
|
|
markAsAutomaticallyClosed() {
|
|
this._popupAutomaticallyClosed = true;
|
|
}
|
|
|
|
/**
|
|
* Either brings an existing MetaMask notification window into focus, or creates a new notification window. New
|
|
* notification windows are given a 'popup' type.
|
|
*
|
|
*/
|
|
async showPopup() {
|
|
const popup = await this._getPopup();
|
|
|
|
// Bring focus to chrome popup
|
|
if (popup) {
|
|
// bring focus to existing chrome popup
|
|
await this.platform.focusWindow(popup.id);
|
|
} else {
|
|
let left = 0;
|
|
let top = 0;
|
|
try {
|
|
const lastFocused = await this.platform.getLastFocusedWindow();
|
|
// Position window in top right corner of lastFocused window.
|
|
top = lastFocused.top;
|
|
left = lastFocused.left + (lastFocused.width - NOTIFICATION_WIDTH);
|
|
} catch (_) {
|
|
// The following properties are more than likely 0, due to being
|
|
// opened from the background chrome process for the extension that
|
|
// has no physical dimensions
|
|
const { screenX, screenY, outerWidth } = window;
|
|
top = Math.max(screenY, 0);
|
|
left = Math.max(screenX + (outerWidth - NOTIFICATION_WIDTH), 0);
|
|
}
|
|
|
|
// create new notification popup
|
|
const popupWindow = await this.platform.openWindow({
|
|
url: 'notification.html',
|
|
type: 'popup',
|
|
width: NOTIFICATION_WIDTH,
|
|
height: NOTIFICATION_HEIGHT,
|
|
left,
|
|
top,
|
|
});
|
|
|
|
// Firefox currently ignores left/top for create, but it works for update
|
|
if (popupWindow.left !== left && popupWindow.state !== 'fullscreen') {
|
|
await this.platform.updateWindowPosition(popupWindow.id, left, top);
|
|
}
|
|
this._popupId = popupWindow.id;
|
|
}
|
|
}
|
|
|
|
_onWindowClosed(windowId) {
|
|
if (windowId === this._popupId) {
|
|
this._popupId = undefined;
|
|
this.emit(NOTIFICATION_MANAGER_EVENTS.POPUP_CLOSED, {
|
|
automaticallyClosed: this._popupAutomaticallyClosed,
|
|
});
|
|
this._popupAutomaticallyClosed = undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks all open MetaMask windows, and returns the first one it finds that is a notification window (i.e. has the
|
|
* type 'popup')
|
|
*
|
|
* @private
|
|
*/
|
|
async _getPopup() {
|
|
const windows = await this.platform.getAllWindows();
|
|
return this._getPopupIn(windows);
|
|
}
|
|
|
|
/**
|
|
* Given an array of windows, returns the 'popup' that has been opened by MetaMask, or null if no such window exists.
|
|
*
|
|
* @private
|
|
* @param {Array} windows - An array of objects containing data about the open MetaMask extension windows.
|
|
*/
|
|
_getPopupIn(windows) {
|
|
return windows
|
|
? windows.find((win) => {
|
|
// Returns notification popup
|
|
return win && win.type === 'popup' && win.id === this._popupId;
|
|
})
|
|
: null;
|
|
}
|
|
}
|