1
0
mirror of https://github.com/moparisthebest/mail synced 2024-11-26 10:52:17 -05:00

[WO-627] Expose all IMAP folders to account.folders

This commit is contained in:
Felix Hammerl 2014-10-16 12:23:49 +02:00 committed by Tankred Hase
parent 52a2f4f43a
commit b96ae1dd89
3 changed files with 110 additions and 53 deletions

View File

@ -16,10 +16,12 @@ var SYNC_TYPE_NEW = 'new';
var SYNC_TYPE_DELETED = 'deleted'; var SYNC_TYPE_DELETED = 'deleted';
var SYNC_TYPE_MSGS = 'messages'; var SYNC_TYPE_MSGS = 'messages';
// well known folders
var FOLDER_TYPE_INBOX = 'Inbox'; var FOLDER_TYPE_INBOX = 'Inbox';
var FOLDER_TYPE_SENT = 'Sent'; var FOLDER_TYPE_SENT = 'Sent';
var FOLDER_TYPE_DRAFTS = 'Drafts'; var FOLDER_TYPE_DRAFTS = 'Drafts';
var FOLDER_TYPE_TRASH = 'Trash'; var FOLDER_TYPE_TRASH = 'Trash';
var FOLDER_TYPE_FLAGGED = 'Flagged';
var MSG_ATTR_UID = 'uid'; var MSG_ATTR_UID = 'uid';
var MSG_PART_ATTR_CONTENT = 'content'; var MSG_PART_ATTR_CONTENT = 'content';
@ -1348,6 +1350,9 @@ EmailDAO.prototype._initFoldersFromImap = function(callback) {
// fetch list from imap server // fetch list from imap server
self._imapClient.listWellKnownFolders(function(err, wellKnownFolders) { self._imapClient.listWellKnownFolders(function(err, wellKnownFolders) {
var foldersChanged = false, // indicates if we need to persist anything to disk
imapFolders = []; // aggregate all the imap folders
if (err) { if (err) {
return done(err); return done(err);
} }
@ -1355,52 +1360,80 @@ EmailDAO.prototype._initFoldersFromImap = function(callback) {
// initialize the folders to something meaningful if that hasn't already happened // initialize the folders to something meaningful if that hasn't already happened
self._account.folders = self._account.folders || []; self._account.folders = self._account.folders || [];
// smuggle the outbox into the well known folders, which is obv not present on imap... // smuggle the outbox into the well known folders, which is obv not present on imap
wellKnownFolders[config.outboxMailboxType] = [{ wellKnownFolders[config.outboxMailboxType] = [{
name: config.outboxMailboxName, name: config.outboxMailboxName,
type: config.outboxMailboxType, type: config.outboxMailboxType,
path: config.outboxMailboxPath path: config.outboxMailboxPath
}]; }];
// indicates if we need to persist anything to disk // aggregate all of the imap folders in one place
var foldersChanged = false; for (var folderType in wellKnownFolders) {
if (wellKnownFolders.hasOwnProperty(folderType) && Array.isArray(wellKnownFolders[folderType])) {
imapFolders = imapFolders.concat(wellKnownFolders[folderType]);
}
}
// the folders listed in the navigation pane // find out all the imap paths that are new/removed
[FOLDER_TYPE_INBOX, FOLDER_TYPE_SENT, config.outboxMailboxType, FOLDER_TYPE_DRAFTS, FOLDER_TYPE_TRASH].forEach(function(mbxType) { var imapFolderPaths = _.pluck(imapFolders, 'path'),
var localFolderWithType, imapFolderWithPath; localFolderPaths = _.pluck(self._account.folders, 'path'),
newFolderPaths = _.difference(imapFolderPaths, localFolderPaths),
removedFolderPaths = _.difference(localFolderPaths, imapFolderPaths);
// check if there is a folder of this type locally available // folders need updating if there are new/removed folders
localFolderWithType = _.findWhere(self._account.folders, { foldersChanged = !!newFolderPaths.length || !!removedFolderPaths.length;
// remove all the remotely deleted folders
removedFolderPaths.forEach(function(removedPath) {
self._account.folders.splice(self._account.folders.indexOf(_.findWhere(self._account.folders, {
path: removedPath
})), 1);
});
// add all the new imap folders
newFolderPaths.forEach(function(newPath) {
self._account.folders.push(_.findWhere(imapFolders, {
path: newPath
}));
});
//
// by now, all the folders are up to date. now we need to find all the well known folders
//
// check for the well known folders to be displayed in the uppermost ui part
[
FOLDER_TYPE_INBOX,
FOLDER_TYPE_SENT,
config.outboxMailboxType,
FOLDER_TYPE_DRAFTS,
FOLDER_TYPE_FLAGGED,
FOLDER_TYPE_TRASH
].forEach(function(mbxType) {
// check if there is a well known folder of this type
var wellknownFolder = _.findWhere(self._account.folders, {
type: mbxType,
wellknown: true
});
if (wellknownFolder) {
// well known folder found, no need to find a replacement
return;
}
// we have no folder of the respective type marked as wellknown, so find the
// next best folder of the respective type and flag it as wellknown so that
// we can display it properly
wellknownFolder = _.findWhere(self._account.folders, {
type: mbxType type: mbxType
}); });
if (localFolderWithType) { if (!wellknownFolder) {
// we have a local folder available, so let's check if this folder still exists on imap // no folder of that type, to mark as well known, nothing to do here
imapFolderWithPath = _.findWhere(wellKnownFolders[mbxType], {
path: localFolderWithType.path
});
if (imapFolderWithPath) {
// folder present on imap, no need to update.
return; return;
} }
// folder not present on imap, so remove the folder and see if there are any updates for this folder type wellknownFolder.wellknown = true;
self._account.folders.splice(self._account.folders.indexOf(localFolderWithType), 1);
foldersChanged = true;
}
if (!wellKnownFolders[mbxType] || !wellKnownFolders[mbxType].length) {
// no imap folders of the respective mailbox type, so nothing to do here
return;
}
/**
* we have no local folder of the type, so do something intelligent,
* i.e. take the first folder of the respective type
*/
self._account.folders.push(wellKnownFolders[mbxType][0]);
foldersChanged = true; foldersChanged = true;
}); });
@ -1415,9 +1448,11 @@ EmailDAO.prototype._initFoldersFromImap = function(callback) {
return { return {
name: folder.name, name: folder.name,
path: folder.path, path: folder.path,
type: folder.type type: folder.type,
wellknown: !!folder.wellknown
}; };
}); });
self._devicestorage.storeList([folders], FOLDER_DB_TYPE, function(err) { self._devicestorage.storeList([folders], FOLDER_DB_TYPE, function(err) {
if (err) { if (err) {
return done(err); return done(err);

View File

@ -6,7 +6,7 @@
<ul class="nav-primary"> <ul class="nav-primary">
<li ng-repeat="folder in account.folders" ng-switch="folder.count !== undefined && folder.count > 0"> <li ng-repeat="folder in account.folders" ng-switch="folder.count !== undefined && folder.count > 0">
<a href="#" wo-touch="openFolder(folder); $event.preventDefault()"> <a href="#" wo-touch="openFolder(folder); $event.preventDefault()">
{{folder.type}} {{folder.wellknown? folder.type : folder.name}}
<span class="label-wrapper" ng-switch-when="true"> <span class="label-wrapper" ng-switch-when="true">
<span class="label label-light">{{folder.count}}</span> <span class="label label-light">{{folder.count}}</span>
</span> </span>

View File

@ -25,7 +25,7 @@ describe('Email DAO unit tests', function() {
var emailAddress, passphrase, asymKeySize, account; var emailAddress, passphrase, asymKeySize, account;
// test data // test data
var folders, inboxFolder, sentFolder, draftsFolder, outboxFolder, trashFolder, mockKeyPair; var folders, inboxFolder, sentFolder, draftsFolder, outboxFolder, trashFolder, otherFolder, mockKeyPair;
beforeEach(function() { beforeEach(function() {
// //
@ -70,7 +70,14 @@ describe('Email DAO unit tests', function() {
messages: [] messages: []
}; };
folders = [inboxFolder, outboxFolder, trashFolder, sentFolder]; otherFolder = {
name: 'Other',
type: 'Other',
path: 'OTHER',
messages: []
};
folders = [inboxFolder, outboxFolder, trashFolder, sentFolder, otherFolder];
account = { account = {
emailAddress: emailAddress, emailAddress: emailAddress,
@ -1995,7 +2002,8 @@ describe('Email DAO unit tests', function() {
Inbox: [inboxFolder], Inbox: [inboxFolder],
Sent: [sentFolder], Sent: [sentFolder],
Drafts: [draftsFolder], Drafts: [draftsFolder],
Trash: [trashFolder] Trash: [trashFolder],
Other: [otherFolder]
}); });
devicestorageStub.storeList.withArgs(sinon.match(function(arg) { devicestorageStub.storeList.withArgs(sinon.match(function(arg) {
expect(arg[0][0].name).to.deep.equal(inboxFolder.name); expect(arg[0][0].name).to.deep.equal(inboxFolder.name);
@ -2004,15 +2012,18 @@ describe('Email DAO unit tests', function() {
expect(arg[0][1].name).to.deep.equal(sentFolder.name); expect(arg[0][1].name).to.deep.equal(sentFolder.name);
expect(arg[0][1].path).to.deep.equal(sentFolder.path); expect(arg[0][1].path).to.deep.equal(sentFolder.path);
expect(arg[0][1].type).to.deep.equal(sentFolder.type); expect(arg[0][1].type).to.deep.equal(sentFolder.type);
expect(arg[0][2].name).to.deep.equal(outboxFolder.name); expect(arg[0][2].name).to.deep.equal(draftsFolder.name);
expect(arg[0][2].path).to.deep.equal(outboxFolder.path); expect(arg[0][2].path).to.deep.equal(draftsFolder.path);
expect(arg[0][2].type).to.deep.equal(outboxFolder.type); expect(arg[0][2].type).to.deep.equal(draftsFolder.type);
expect(arg[0][3].name).to.deep.equal(draftsFolder.name); expect(arg[0][3].name).to.deep.equal(trashFolder.name);
expect(arg[0][3].path).to.deep.equal(draftsFolder.path); expect(arg[0][3].path).to.deep.equal(trashFolder.path);
expect(arg[0][3].type).to.deep.equal(draftsFolder.type); expect(arg[0][3].type).to.deep.equal(trashFolder.type);
expect(arg[0][4].name).to.deep.equal(trashFolder.name); expect(arg[0][4].name).to.deep.equal(otherFolder.name);
expect(arg[0][4].path).to.deep.equal(trashFolder.path); expect(arg[0][4].path).to.deep.equal(otherFolder.path);
expect(arg[0][4].type).to.deep.equal(trashFolder.type); expect(arg[0][4].type).to.deep.equal(otherFolder.type);
expect(arg[0][5].name).to.deep.equal(outboxFolder.name);
expect(arg[0][5].path).to.deep.equal(outboxFolder.path);
expect(arg[0][5].type).to.deep.equal(outboxFolder.type);
return true; return true;
}), 'folders').yieldsAsync(); }), 'folders').yieldsAsync();
@ -2037,29 +2048,40 @@ describe('Email DAO unit tests', function() {
Inbox: [inboxFolder], Inbox: [inboxFolder],
Sent: [sentFolder], Sent: [sentFolder],
Drafts: [draftsFolder], Drafts: [draftsFolder],
Trash: [trashFolder] Trash: [trashFolder],
Other: [otherFolder]
}); });
devicestorageStub.storeList.withArgs(sinon.match(function(arg) { devicestorageStub.storeList.withArgs(sinon.match(function(arg) {
expect(arg[0]).to.deep.equal([{ expect(arg[0]).to.deep.equal([{
name: inboxFolder.name, name: inboxFolder.name,
path: inboxFolder.path, path: inboxFolder.path,
type: inboxFolder.type type: inboxFolder.type,
wellknown: true
}, { }, {
name: outboxFolder.name, name: outboxFolder.name,
path: outboxFolder.path, path: outboxFolder.path,
type: outboxFolder.type type: outboxFolder.type,
wellknown: true
}, { }, {
name: trashFolder.name, name: trashFolder.name,
path: trashFolder.path, path: trashFolder.path,
type: trashFolder.type type: trashFolder.type,
wellknown: true
}, { }, {
name: sentFolder.name, name: sentFolder.name,
path: sentFolder.path, path: sentFolder.path,
type: sentFolder.type type: sentFolder.type,
wellknown: true
}, { }, {
name: draftsFolder.name, name: draftsFolder.name,
path: draftsFolder.path, path: draftsFolder.path,
type: draftsFolder.type type: draftsFolder.type,
wellknown: true
}, {
name: otherFolder.name,
path: otherFolder.path,
type: otherFolder.type,
wellknown: false
}]); }]);
return true; return true;