You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			216 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			216 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
/*global $, Whisper, Backbone, textsecure, extension*/
 | 
						|
 | 
						|
// This script should only be included in background.html
 | 
						|
(function() {
 | 
						|
  'use strict';
 | 
						|
 | 
						|
  window.Whisper = window.Whisper || {};
 | 
						|
 | 
						|
  var conversations = new Whisper.ConversationCollection();
 | 
						|
  var inboxCollection = new (Backbone.Collection.extend({
 | 
						|
    initialize: function() {
 | 
						|
      this.on('change:timestamp change:name change:number', this.sort);
 | 
						|
 | 
						|
      this.listenTo(conversations, 'add change:active_at', this.addActive);
 | 
						|
      this.listenTo(conversations, 'reset', function() {
 | 
						|
        this.reset([]);
 | 
						|
      });
 | 
						|
 | 
						|
      this.on(
 | 
						|
        'add remove change:unreadCount',
 | 
						|
        _.debounce(this.updateUnreadCount.bind(this), 1000)
 | 
						|
      );
 | 
						|
      this.startPruning();
 | 
						|
 | 
						|
      this.collator = new Intl.Collator();
 | 
						|
    },
 | 
						|
    comparator: function(m1, m2) {
 | 
						|
      var timestamp1 = m1.get('timestamp');
 | 
						|
      var timestamp2 = m2.get('timestamp');
 | 
						|
      if (timestamp1 && !timestamp2) {
 | 
						|
        return -1;
 | 
						|
      }
 | 
						|
      if (timestamp2 && !timestamp1) {
 | 
						|
        return 1;
 | 
						|
      }
 | 
						|
      if (timestamp1 && timestamp2 && timestamp1 !== timestamp2) {
 | 
						|
        return timestamp2 - timestamp1;
 | 
						|
      }
 | 
						|
 | 
						|
      var title1 = m1.getTitle().toLowerCase();
 | 
						|
      var title2 = m2.getTitle().toLowerCase();
 | 
						|
      return this.collator.compare(title1, title2);
 | 
						|
    },
 | 
						|
    addActive: function(model) {
 | 
						|
      if (model.get('active_at')) {
 | 
						|
        this.add(model);
 | 
						|
      } else {
 | 
						|
        this.remove(model);
 | 
						|
      }
 | 
						|
    },
 | 
						|
    updateUnreadCount: function() {
 | 
						|
      var newUnreadCount = _.reduce(
 | 
						|
        this.map(function(m) {
 | 
						|
          return m.get('unreadCount');
 | 
						|
        }),
 | 
						|
        function(item, memo) {
 | 
						|
          return item + memo;
 | 
						|
        },
 | 
						|
        0
 | 
						|
      );
 | 
						|
      storage.put('unreadCount', newUnreadCount);
 | 
						|
 | 
						|
      if (newUnreadCount > 0) {
 | 
						|
        window.setBadgeCount(newUnreadCount);
 | 
						|
        window.document.title =
 | 
						|
          window.config.title + ' (' + newUnreadCount + ')';
 | 
						|
      } else {
 | 
						|
        window.setBadgeCount(0);
 | 
						|
        window.document.title = window.config.title;
 | 
						|
      }
 | 
						|
      window.updateTrayIcon(newUnreadCount);
 | 
						|
    },
 | 
						|
    startPruning: function() {
 | 
						|
      var halfHour = 30 * 60 * 1000;
 | 
						|
      this.interval = setInterval(
 | 
						|
        function() {
 | 
						|
          this.forEach(function(conversation) {
 | 
						|
            conversation.trigger('prune');
 | 
						|
          });
 | 
						|
        }.bind(this),
 | 
						|
        halfHour
 | 
						|
      );
 | 
						|
    },
 | 
						|
  }))();
 | 
						|
 | 
						|
  window.getInboxCollection = function() {
 | 
						|
    return inboxCollection;
 | 
						|
  };
 | 
						|
 | 
						|
  window.ConversationController = {
 | 
						|
    get: function(id) {
 | 
						|
      if (!this._initialFetchComplete) {
 | 
						|
        throw new Error(
 | 
						|
          'ConversationController.get() needs complete initial fetch'
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      return conversations.get(id);
 | 
						|
    },
 | 
						|
    // Needed for some model setup which happens during the initial fetch() call below
 | 
						|
    getUnsafe: function(id) {
 | 
						|
      return conversations.get(id);
 | 
						|
    },
 | 
						|
    dangerouslyCreateAndAdd: function(attributes) {
 | 
						|
      return conversations.add(attributes);
 | 
						|
    },
 | 
						|
    getOrCreate: function(id, type) {
 | 
						|
      if (typeof id !== 'string') {
 | 
						|
        throw new TypeError("'id' must be a string");
 | 
						|
      }
 | 
						|
 | 
						|
      if (type !== 'private' && type !== 'group') {
 | 
						|
        throw new TypeError(
 | 
						|
          `'type' must be 'private' or 'group'; got: '${type}'`
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      if (!this._initialFetchComplete) {
 | 
						|
        throw new Error(
 | 
						|
          'ConversationController.get() needs complete initial fetch'
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      var conversation = conversations.get(id);
 | 
						|
      if (conversation) {
 | 
						|
        return conversation;
 | 
						|
      }
 | 
						|
 | 
						|
      conversation = conversations.add({
 | 
						|
        id: id,
 | 
						|
        type: type,
 | 
						|
      });
 | 
						|
      conversation.initialPromise = new Promise(function(resolve, reject) {
 | 
						|
        if (!conversation.isValid()) {
 | 
						|
          var validationError = conversation.validationError || {};
 | 
						|
          console.log(
 | 
						|
            'Contact is not valid. Not saving, but adding to collection:',
 | 
						|
            conversation.idForLogging(),
 | 
						|
            validationError.stack
 | 
						|
          );
 | 
						|
 | 
						|
          return resolve(conversation);
 | 
						|
        }
 | 
						|
 | 
						|
        var deferred = conversation.save();
 | 
						|
        if (!deferred) {
 | 
						|
          console.log('Conversation save failed! ', id, type);
 | 
						|
          return reject(new Error('getOrCreate: Conversation save failed'));
 | 
						|
        }
 | 
						|
 | 
						|
        deferred.then(function() {
 | 
						|
          resolve(conversation);
 | 
						|
        }, reject);
 | 
						|
      });
 | 
						|
 | 
						|
      return conversation;
 | 
						|
    },
 | 
						|
    getOrCreateAndWait: function(id, type) {
 | 
						|
      return this._initialPromise.then(
 | 
						|
        function() {
 | 
						|
          var conversation = this.getOrCreate(id, type);
 | 
						|
 | 
						|
          if (conversation) {
 | 
						|
            return conversation.initialPromise.then(function() {
 | 
						|
              return conversation;
 | 
						|
            });
 | 
						|
          }
 | 
						|
 | 
						|
          return Promise.reject(
 | 
						|
            new Error('getOrCreateAndWait: did not get conversation')
 | 
						|
          );
 | 
						|
        }.bind(this)
 | 
						|
      );
 | 
						|
    },
 | 
						|
    getAllGroupsInvolvingId: function(id) {
 | 
						|
      var groups = new Whisper.GroupCollection();
 | 
						|
      return groups.fetchGroups(id).then(function() {
 | 
						|
        return groups.map(function(group) {
 | 
						|
          return conversations.add(group);
 | 
						|
        });
 | 
						|
      });
 | 
						|
    },
 | 
						|
    loadPromise: function() {
 | 
						|
      return this._initialPromise;
 | 
						|
    },
 | 
						|
    reset: function() {
 | 
						|
      this._initialPromise = Promise.resolve();
 | 
						|
      conversations.reset([]);
 | 
						|
    },
 | 
						|
    load: function() {
 | 
						|
      console.log('ConversationController: starting initial fetch');
 | 
						|
 | 
						|
      this._initialPromise = new Promise(
 | 
						|
        function(resolve, reject) {
 | 
						|
          conversations.fetch().then(
 | 
						|
            function() {
 | 
						|
              console.log('ConversationController: done with initial fetch');
 | 
						|
              this._initialFetchComplete = true;
 | 
						|
              resolve();
 | 
						|
            }.bind(this),
 | 
						|
            function(error) {
 | 
						|
              console.log(
 | 
						|
                'ConversationController: initial fetch failed',
 | 
						|
                error && error.stack ? error.stack : error
 | 
						|
              );
 | 
						|
              reject(error);
 | 
						|
            }
 | 
						|
          );
 | 
						|
        }.bind(this)
 | 
						|
      );
 | 
						|
 | 
						|
      return this._initialPromise;
 | 
						|
    },
 | 
						|
  };
 | 
						|
})();
 |