JSDoc: Source: jsxc.lib.gui.avatar.js

# Source: jsxc.lib.gui.avatar.js

    jsxc.gui.avatar = {
       queue: [],

       PLACEHOLDER: 0,

       DELAY: 300,

       CHUNKSIZE: 20,

       timeout: null,

       lastRun: 0
    };

    /**
     * Update avatar on all given elements.
     *
     * @memberOf jsxc.gui
     * @param {jQuery} el Elements with subelement .jsxc_avatar
     * @param {string} jid Jid
     * @param {string} aid Avatar id (sha1 hash of image)
     */
    jsxc.gui.avatar.update = function(el, jid, aid) {
       var self = jsxc.gui.avatar;

       if (typeof aid === 'undefined') {
          self.set(jid, el, self.PLACEHOLDER);
          return;
       }

       var avatarSrc = jsxc.storage.getUserItem('avatar', aid);

       if (!jsxc.master && !avatarSrc) {
          // force avatar placeholder for slave tab, until master tab requested vCard
          avatarSrc = self.PLACEHOLDER;
       }

       if (avatarSrc !== null) {
          self.set(jid, el, avatarSrc);
       } else {
          var handler_cb = function(stanza) {
             var src = jsxc.gui.avatar.getPhotoFromVcard(stanza);

             jsxc.storage.setUserItem('avatar', aid, src);
             self.set(jid, el, src);
          };

          var error_cb = function(msg) {
             jsxc.warn('Could not load vcard.', msg);

             jsxc.storage.setUserItem('avatar', aid, self.PLACEHOLDER);
             self.set(jid, el, self.PLACEHOLDER);
          };

          var args = [];

          // workaround for https://github.com/strophe/strophejs/issues/172
          if (Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(jsxc.xmpp.conn.jid)) {
             args = [handler_cb, error_cb];
          } else {
             args = [handler_cb, Strophe.getBareJidFromJid(jid), error_cb];
          }

          jsxc.gui.avatar.queueAction(jid, jsxc.xmpp.conn.vcard.get, args, jsxc.xmpp.conn.vcard);
       }
    };

    jsxc.gui.avatar.getPhotoFromVcard = function(stanza) {
       jsxc.debug('vCard', stanza);

       var vCard = $(stanza).find("vCard > PHOTO");
       var src;

       if (vCard.length === 0) {
          jsxc.debug('No photo provided');
          src = '0';
       } else if (vCard.find('EXTVAL').length > 0) {
          src = vCard.find('EXTVAL').text();
       } else {
          var img = vCard.find('BINVAL').text();
          var type = vCard.find('TYPE').text();
          src = 'data:' + type + ';base64,' + img;
       }

       // concat chunks
       src = src.replace(/[\t\r\n\f]/gi, '');

       return src;
    };

    jsxc.gui.avatar.set = function(jid, el, src) {
       var self = jsxc.gui.avatar;

       if (src === self.PLACEHOLDER || src === '0') {
          if (typeof jsxc.options.defaultAvatar === 'function') {
             jsxc.gui.avatar.queueAction(jid, function() {
                jsxc.options.defaultAvatar.call(el, jid);
             });
             return;
          }
          jsxc.gui.avatarPlaceholder(el.find('.jsxc_avatar'), jid);
          return;
       }

       el.find('.jsxc_avatar').removeAttr('style');

       el.find('.jsxc_avatar').css({
          'background-image': 'url(' + src + ')',
          'text-indent': '999px'
       });
    };

    jsxc.gui.avatar.queueAction = function(jid, fn, args, context) {
       var self = jsxc.gui.avatar;
       var bid = jsxc.jidToBid(jid);
       var data = jsxc.storage.getUserItem('buddy', bid) || {};
       var state = data.status;

       var index = self.queue.indexOf(bid);
       if (index > -1) {
          self.queue.splice(index, 1);
       }

       var action = {
          fn: fn,
          args: args || [],
          context: context || this
       };

       if (state === 0) {
          self.queue.push(action);
       } else {
          self.queue.unshift(action);
       }

       jsxc.gui.avatar.processQueue();
    };

    jsxc.gui.avatar.processQueue = function() {
       var self = jsxc.gui.avatar;
       var currentTime = (new Date()).getTime();

       if (currentTime - self.lastRun < self.DELAY) {
          if (!self.timeout) {
             self.timeout = setTimeout(self.processQueue, self.DELAY);
          }
          return;
       }

       self.lastRun = currentTime;

       var i, action;
       for (i = 0; i < self.CHUNKSIZE; i++) {
          if (self.queue.length > 0) {
             action = self.queue.shift();
             action.fn.apply(action.context, action.args);
          }
       }

       if (self.queue.length > 0) {
          self.timeout = setTimeout(self.processQueue, self.DELAY);
       } else {
          self.timeout = null;
       }
    };