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.
		
		
		
		
		
			
		
			
				
	
	
		
			199 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			199 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
/*global $, Whisper, Backbone, textsecure, extension*/
 | 
						|
/*
 | 
						|
 * vim: ts=4:sw=4:expandtab
 | 
						|
 */
 | 
						|
 | 
						|
// 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;
 | 
						|
        }
 | 
						|
    };
 | 
						|
})();
 |