aboutsummaryrefslogblamecommitdiffstats
path: root/app/scripts/lib/notification-manager.js
blob: 721d109a1a952e92c66bf45f38b8a65832accb1e (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
                                          

                               


                           





                                                                                              
 




                                                                                                                 
                
                                    

                        
                                    
                  
                                               

                                                             
                                                                  

                                                                                                   
                                                                        
                                        
                                                   

                                   



                                              

                                                      



       



                                                        
                 
                                
                                    





                                                       







                                                                                                                     






                                         






                                                                                         










                                               
     
                                                                                                                       




                                                                                                          

                                            
                                   
                                                                      




             
                                    
const extension = require('extensionizer')
const NOTIFICATION_HEIGHT = 620
const NOTIFICATION_WIDTH = 360

class NotificationManager {

  /**
   * A collection of methods for controlling the showing and hiding of the notification popup.
   *
   * @typedef {Object} NotificationManager
   *
   */

  /**
   * Either brings an existing MetaMask notification window into focus, or creates a new notification window. New
   * notification windows are given a 'popup' type.
   *
   */
  showPopup () {
    this._getPopup((err, popup) => {
      if (err) throw err

      // Bring focus to chrome popup
      if (popup) {
        // bring focus to existing chrome popup
        extension.windows.update(popup.id, { focused: true })
      } else {
        const {screenX, screenY, outerWidth, outerHeight} = window
        const notificationTop = Math.round(screenY + (outerHeight / 2) - (NOTIFICATION_HEIGHT / 2))
        const notificationLeft = Math.round(screenX + (outerWidth / 2) - (NOTIFICATION_WIDTH / 2))
        const cb = (currentPopup) => { this._popupId = currentPopup.id }
        // create new notification popup
        const creation = extension.windows.create({
          url: 'notification.html',
          type: 'popup',
          width: NOTIFICATION_WIDTH,
          height: NOTIFICATION_HEIGHT,
          top: Math.max(notificationTop, 0),
          left: Math.max(notificationLeft, 0),
        }, cb)
        creation && creation.then && creation.then(cb)
      }
    })
  }

  /**
   * Closes a MetaMask notification if it window exists.
   *
   */
  closePopup () {
    // closes notification popup
    this._getPopup((err, popup) => {
      if (err) throw err
      if (!popup) return
      extension.windows.remove(popup.id, console.error)
    })
  }

  /**
   * Checks all open MetaMask windows, and returns the first one it finds that is a notification window (i.e. has the
   * type 'popup')
   *
   * @private
   * @param {Function} cb A node style callback that to whcih the found notification window will be passed.
   *
   */
  _getPopup (cb) {
    this._getWindows((err, windows) => {
      if (err) 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)
    })
  }

  /**
   * 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
  }

}

module.exports = NotificationManager