sogo/UI/WebServerResources/js/Mailer/VirtualMailbox.service.js

403 lines
12 KiB
JavaScript

/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
(function() {
'use strict';
/**
* @name VirtualMailbox
* @constructor
* @param {object} account - the mail account associated with the virtual search
*/
function VirtualMailbox(account) {
this.$account = account;
}
/**
* @memberof VirtualMailbox
* @desc The factory we'll use to register with Angular
* @returns the VirtualMailbox constructor
*/
VirtualMailbox.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'Resource', 'Message', 'Mailbox', 'sgMailbox_PRELOAD', function($q, $timeout, $log, Settings, Resource, Mailbox, Message, PRELOAD) {
angular.extend(VirtualMailbox, {
$q: $q,
$timeout: $timeout,
$log: $log,
$$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()),
$Message: Message,
selectedFolder: null,
PRELOAD: PRELOAD
});
return VirtualMailbox; // return constructor
}];
/**
* @module SOGo.MailerUI
* @desc Factory registration of VirtualMailbox in Angular module.
*/
try {
angular.module('SOGo.MailerUI');
}
catch(e) {
angular.module('SOGo.MailerUI', ['SOGo.Common']);
}
angular.module('SOGo.MailerUI')
.constant('sgMailbox_PRELOAD', {
LOOKAHEAD: 50,
SIZE: 100
})
.factory('VirtualMailbox', VirtualMailbox.$factory);
/**
* @memberof VirtualMailbox
* @desc Build the path of the virtual mailbox (or account only).
* @param {string} accountId - the account ID
* @returns a string representing the path relative to the mail module
*/
VirtualMailbox.$absolutePath = function(accountId) {
return [accountId, "virtual"].join('/');
};
/**
* @function init
* @memberof VirtualMailbox.prototype
* @desc Extend instance with new data and compute additional attributes.
* @param {object} data - attributes of mailbox
*/
VirtualMailbox.prototype.init = function(data) {
this.$isLoading = false;
this.$mailboxes = [];
this.uidsMap = {};
angular.extend(this, data);
this.id = this.$id();
};
VirtualMailbox.prototype.setMailboxes = function(data) {
this.$mailboxes = data;
_.forEach(this.$mailboxes, function(mailbox) {
mailbox.$messages = [];
mailbox.uidsMap = {};
});
};
VirtualMailbox.prototype.startSearch = function(match, params) {
var _this = this,
search = VirtualMailbox.$q.when();
this.$isLoading = true;
_.forEach(this.$mailboxes, function(mailbox) {
search = search.then(function() {
if (_this.$isLoading) {
VirtualMailbox.$log.debug("searching mailbox " + mailbox.path);
return mailbox.$filter( {sort: "date", asc: false, match: match}, params);
}
});
});
search.finally(function() {
_this.$isLoading = false;
});
};
VirtualMailbox.prototype.stopSearch = function() {
VirtualMailbox.$log.debug("stopping search...");
this.$isLoading = false;
};
/**
* @function selectFolder
* @memberof VirtualMailbox.prototype
* @desc A no-op for virtual mailbox
*/
VirtualMailbox.prototype.selectFolder = function() {
return;
};
/**
* @function resetSelectedMessage
* @memberof VirtualMailbox.prototype
* @desc Delete 'selectedMessage' attribute of all submailboxes.
*/
VirtualMailbox.prototype.resetSelectedMessage = function() {
_.forEach(this.$mailboxes, function(mailbox) {
delete mailbox.$selectedMessage;
});
};
/**
* @function hasSelectedMessage
* @memberof VirtualMailbox.prototype
* @desc Check if a message is selected among the resulting mailboxes
* @returns true if one message is selected
*/
VirtualMailbox.prototype.hasSelectedMessage = function() {
return angular.isDefined(_.find(this.$mailboxes, function(mailbox) {
return angular.isDefined(mailbox.$selectedMessage);
}));
};
/**
* @function isSelectedMessage
* @memberof VirtualMailbox.prototype
* @desc Check if the message of the specified mailbox is selected.
* @param {string} messageId
* @param {string} mailboxPath
* @returns true if the specified message is selected
*/
VirtualMailbox.prototype.isSelectedMessage = function(messageId, mailboxPath) {
return angular.isDefined(_.find(this.$mailboxes, function(mailbox) {
return mailbox.path == mailboxPath && mailbox.$selectedMessage == messageId;
}));
};
/**
* @function getLength
* @memberof VirtualMailbox.prototype
* @desc Used by md-virtual-repeat / md-on-demand
* @returns the number of items in the mailbox
*/
VirtualMailbox.prototype.getLength = function() {
var len = 0;
if (!angular.isDefined(this.$mailboxes))
return len;
_.forEach(this.$mailboxes, function(mailbox) {
len += mailbox.$messages.length;
});
return len;
};
/**
* @function getItemAtIndex
* @memberof VirtualMailbox.prototype
* @desc Used by md-virtual-repeat / md-on-demand
* @returns the message as the specified index
*/
VirtualMailbox.prototype.getItemAtIndex = function(index) {
var i, j, k, mailbox, message;
if (angular.isDefined(this.$mailboxes) && index >= 0) {
i = 0;
for (j = 0; j < this.$mailboxes.length; j++) {
mailbox = this.$mailboxes[j];
for (k = 0; k < mailbox.$messages.length; i++, k++) {
if (i == index) {
message = mailbox.$messages[k];
if (mailbox.$loadMessage(message.uid))
return message;
}
}
}
}
return null;
};
/**
* @function $id
* @memberof VirtualMailbox.prototype
* @desc Build the unique ID to identified the mailbox.
* @returns a string representing the path relative to the mail module
*/
VirtualMailbox.prototype.$id = function() {
return VirtualMailbox.$absolutePath(this.$account.id);
};
/**
* @function $selectedMessageIndex
* @memberof Mailbox.prototype
* @desc Return the index of the currently visible message.
* @returns a number or undefined if no message is selected
*/
VirtualMailbox.prototype.$selectedMessageIndex = function() {
var offset = 0;
var selectedMailbox = _.find(this.$mailboxes, function(mailbox) {
if (angular.isDefined(mailbox.$selectedMessage)) {
return true;
}
else {
offset += mailbox.getLength();
return false;
}
});
return offset + selectedMailbox.uidsMap[selectedMailbox.$selectedMessage];
};
/**
* @function $selectedMessages
* @memberof VirtualMailbox.prototype
* @desc Return an associative array of the selected messages for each mailbox. Keys are the mailboxes ids.
* @returns an associative array
*/
VirtualMailbox.prototype.selectedMessages = function() {
var messagesMap = {};
return _.filter(_.transform(this.$mailboxes, function(messagesMap, mailbox) {
messagesMap[mailbox.id] = mailbox.$selectedMessages;
}, {}), function(o) {
return _.size(o) > 0;
});
};
/**
* @function selectedCount
* @memberof VirtualMailbox.prototype
* @desc Return the number of messages selected by the user.
* @returns the number of selected messages
*/
VirtualMailbox.prototype.selectedCount = function() {
return _.sum(_.invokeMap(this.$mailboxes, 'selectedCount'));
};
/**
* @function $flagMessages
* @memberof VirtualMailbox.prototype
* @desc Add or remove a flag on a message set
* @param {object} messagesMap
* @param {array} flags
* @param {string} operation
* @returns a promise of the HTTP operation
*/
VirtualMailbox.prototype.$flagMessages = function(messagesMap, flags, operation) {
var data = {
flags: flags,
operation: operation
};
var allMessages = [];
var promises = [];
_.forEach(messagesMap, function(messages, id) {
if (messages.length > 0) {
var uids = _.map(messages, 'uid');
allMessages.push(messages);
var promise = VirtualMailbox.$$resource.post(id, 'addOrRemoveLabel', _.assign(data, {msgUIDs: uids}));
promises.push(promise);
}
});
return VirtualMailbox.$q.all(promises).then(function() {
return _.flatten(allMessages);
});
};
/**
* @function $deleteMessages
* @memberof VirtualMailbox.prototype
* @desc Delete one or multiple messages from mailbox.
* @param {object} messagesMap
* @return a promise of the HTTP operation
*/
VirtualMailbox.prototype.$deleteMessages = function(messagesMap) {
var _this = this, promises = [];
if (_.isArray(messagesMap) && messagesMap.length === 1) {
// Deleting one message
var message = messagesMap[0];
var mailbox = message.$mailbox;
return mailbox.$deleteMessages([message]).then(function(index) {
var offset = 0;
_.find(_this.$mailboxes, function(currentMailbox) {
if (currentMailbox.id === mailbox.id) {
return true;
}
else {
offset += currentMailbox.getLength();
return false;
}
});
return offset + index;
});
}
else {
// Deleting multiple messages from different mailboxes
_.forEach(messagesMap, function(messages, id) {
if (messages.length > 0) {
var mailbox = messages[0].$mailbox;
var promise = mailbox.$deleteMessages(messages);
promises.push(promise);
}
});
return VirtualMailbox.$q.all(promises);
}
};
/**
* @function $markOrUnMarkMessagesAsJunk
* @memberof VirtualMailbox.prototype
* @desc Mark messages as junk/not junk
* @param {object} messagesMap
* @return a promise of the HTTP operation
*/
VirtualMailbox.prototype.$markOrUnMarkMessagesAsJunk = function(messagesMap) {
var promises = [];
_.forEach(messagesMap, function(messages, id) {
if (messages.length > 0) {
var mailbox = messages[0].$mailbox;
var promise = mailbox.$markOrUnMarkMessagesAsJunk(messages);
promises.push(promise);
}
});
return VirtualMailbox.$q.all(promises);
};
/**
* @function $copyMessages
* @memberof VirtualMailbox.prototype
* @desc Copy multiple messages from the current mailbox to a target one
* @param {object} messagesMap
* @param {string} folder
* @return a promise of the HTTP operation
*/
VirtualMailbox.prototype.$copyMessages = function(messagesMap, folder) {
var promises = [];
_.forEach(messagesMap, function(messages, id) {
if (messages.length > 0) {
var mailbox = messages[0].$mailbox;
var promise = mailbox.$copyMessages(messages, folder);
promises.push(promise);
}
});
return VirtualMailbox.$q.all(promises);
};
/**
* @function $moveMessages
* @memberof VirtualMailbox.prototype
* @desc Move multiple messages from the current mailbox to a target one
* @param {object} messagesMap
* @param {string} folder
* @return a promise of the HTTP operation
*/
VirtualMailbox.prototype.$moveMessages = function(messagesMap, folder) {
var promises = [];
_.forEach(messagesMap, function(messages, id) {
if (messages.length > 0) {
var mailbox = messages[0].$mailbox;
var promise = mailbox.$moveMessages(messages, folder);
promises.push(promise);
}
});
return VirtualMailbox.$q.all(promises);
};
/**
* @function $compact
* @memberof VirtualMailbox.prototype
* @desc Called when leaving the Mailer module. No-op when in advanced search.
*/
VirtualMailbox.prototype.$comact = function() {
return true;
};
})();