JSDoc: Source: jsxc.lib.notification.js

# Source: jsxc.lib.notification.js

    /**
     * This namespace handles the Notification API.
     *
     * @namespace jsxc.notification
     */
    jsxc.notification = {

       /** Current audio file. */
       audio: null,

       /**
        * Register notification on incoming messages.
        *
        * @memberOf jsxc.notification
        */
       init: function() {
          $(document).on('postmessagein.jsxc', function(event, bid, msg) {
             msg = (msg && msg.match(/^\?OTR/)) ? $.t('Encrypted_message') : msg;
             var data = jsxc.storage.getUserItem('buddy', bid);

             jsxc.notification.notify({
                title: $.t('New_message_from', {
                   name: data.name
                }),
                msg: msg,
                soundFile: jsxc.CONST.SOUNDS.MSG,
                source: bid
             });
          });

          $(document).on('callincoming.jingle', function() {
             jsxc.notification.playSound(jsxc.CONST.SOUNDS.CALL, true, true);
          });

          $(document).on('accept.call.jsxc reject.call.jsxc', function() {
             jsxc.notification.stopSound();
          });
       },

       /**
        * Shows a pop up notification and optional play sound.
        *
        * @param title Title
        * @param msg Message
        * @param d Duration
        * @param force Should message also shown, if tab is visible?
        * @param soundFile Playing given sound file
        * @param loop Loop sound file?
        * @param source Bid which triggered this notification
        */
       notify: function(title, msg, d, force, soundFile, loop, source) {
          if (!jsxc.options.notification || !jsxc.notification.hasPermission()) {
             return; // notifications disabled
          }

          var o;

          if (title !== null && typeof title === 'object') {
             o = title;
          } else {
             o = {
                title: title,
                msg: msg,
                duration: d,
                force: force,
                soundFile: soundFile,
                loop: loop,
                source: source
             };
          }

          if (jsxc.hasFocus() && !o.force) {
             return; // Tab is visible
          }

          var icon = o.icon || jsxc.options.root + '/img/XMPP_logo.png';

          if (typeof o.source === 'string') {
             var data = jsxc.storage.getUserItem('buddy', o.source);
             var src = jsxc.storage.getUserItem('avatar', data.avatar);

             if (typeof src === 'string' && src !== '0') {
                icon = src;
             }
          }

          jsxc.toNotification = setTimeout(function() {

             if (typeof o.soundFile === 'string') {
                jsxc.notification.playSound(o.soundFile, o.loop, o.force);
             }

             var popup = new Notification($.t(o.title), {
                body: $.t(o.msg),
                icon: icon
             });

             var duration = o.duration || jsxc.options.popupDuration;

             if (duration > 0) {
                setTimeout(function() {
                   popup.close();
                }, duration);
             }
          }, jsxc.toNotificationDelay);
       },

       /**
        * Checks if browser has support for notifications and add on chrome to the
        * default api.
        *
        * @returns {Boolean} True if the browser has support.
        */
       hasSupport: function() {
          if (window.webkitNotifications) {
             // prepare chrome

             window.Notification = function(title, opt) {
                var popup = window.webkitNotifications.createNotification(null, title, opt.body);
                popup.show();

                popup.close = function() {
                   popup.cancel();
                };

                return popup;
             };

             var permission;
             switch (window.webkitNotifications.checkPermission()) {
                case 0:
                   permission = jsxc.CONST.NOTIFICATION_GRANTED;
                   break;
                case 2:
                   permission = jsxc.CONST.NOTIFICATION_DENIED;
                   break;
                default: // 1
                   permission = jsxc.CONST.NOTIFICATION_DEFAULT;
             }
             window.Notification.permission = permission;

             window.Notification.requestPermission = function(func) {
                window.webkitNotifications.requestPermission(func);
             };

             return true;
          } else if (window.Notification) {
             return true;
          } else {
             return false;
          }
       },

       /**
        * Ask user on first incoming message if we should inform him about new
        * messages.
        */
       prepareRequest: function() {

          if (jsxc.notice.has('gui.showRequestNotification')) {
             return;
          }

          $(document).one('postmessagein.jsxc', function() {
             setTimeout(function() {
                jsxc.notice.add($.t('Notifications') + '?', $.t('Should_we_notify_you_'), 'gui.showRequestNotification');
             }, 1000);
          });
       },

       /**
        * Request notification permission.
        */
       requestPermission: function() {
          window.Notification.requestPermission(function(status) {
             if (window.Notification.permission !== status) {
                window.Notification.permission = status;
             }

             if (jsxc.notification.hasPermission()) {
                $(document).trigger('notificationready.jsxc');
             } else {
                $(document).trigger('notificationfailure.jsxc');
             }
          });
       },

       /**
        * Check permission.
        *
        * @returns {Boolean} True if we have the permission
        */
       hasPermission: function() {
          return window.Notification.permission === jsxc.CONST.NOTIFICATION_GRANTED;
       },

       /**
        * Plays the given file.
        *
        * @memberOf jsxc.notification
        * @param {string} soundFile File relative to the sound directory
        * @param {boolean} loop True for loop
        * @param {boolean} force Play even if a tab is visible. Default: false.
        */
       playSound: function(soundFile, loop, force) {
          if (!jsxc.master) {
             // only master plays sound
             return;
          }

          if (jsxc.options.get('muteNotification') || jsxc.storage.getUserItem('presence') === 'dnd') {
             // sound mute or own presence is dnd
             return;
          }

          if (jsxc.hasFocus() && !force) {
             // tab is visible
             return;
          }

          // stop current audio file
          jsxc.notification.stopSound();

          var audio = new Audio(jsxc.options.root + '/sound/' + soundFile);
          audio.loop = loop || false;
          audio.play();

          jsxc.notification.audio = audio;
       },

       /**
        * Stop/remove current sound.
        *
        * @memberOf jsxc.notification
        */
       stopSound: function() {
          var audio = jsxc.notification.audio;

          if (typeof audio !== 'undefined' && audio !== null) {
             audio.pause();
             jsxc.notification.audio = null;
          }
       },

       /**
        * Mute sound.
        *
        * @memberOf jsxc.notification
        * @param {boolean} external True if triggered from external tab. Default:
        *        false.
        */
       muteSound: function(external) {
          $('#jsxc_menu .jsxc_muteNotification').text($.t('Unmute'));

          if (external !== true) {
             jsxc.options.set('muteNotification', true);
          }
       },

       /**
        * Unmute sound.
        *
        * @memberOf jsxc.notification
        * @param {boolean} external True if triggered from external tab. Default:
        *        false.
        */
       unmuteSound: function(external) {
          $('#jsxc_menu .jsxc_muteNotification').text($.t('Mute'));

          if (external !== true) {
             jsxc.options.set('muteNotification', false);
          }
       }
    };