mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 02:42:17 -05:00
[WO-627] Expose all IMAP folders to account.folders
This commit is contained in:
parent
52a2f4f43a
commit
b96ae1dd89
@ -16,10 +16,12 @@ var SYNC_TYPE_NEW = 'new';
|
||||
var SYNC_TYPE_DELETED = 'deleted';
|
||||
var SYNC_TYPE_MSGS = 'messages';
|
||||
|
||||
// well known folders
|
||||
var FOLDER_TYPE_INBOX = 'Inbox';
|
||||
var FOLDER_TYPE_SENT = 'Sent';
|
||||
var FOLDER_TYPE_DRAFTS = 'Drafts';
|
||||
var FOLDER_TYPE_TRASH = 'Trash';
|
||||
var FOLDER_TYPE_FLAGGED = 'Flagged';
|
||||
|
||||
var MSG_ATTR_UID = 'uid';
|
||||
var MSG_PART_ATTR_CONTENT = 'content';
|
||||
@ -1348,6 +1350,9 @@ EmailDAO.prototype._initFoldersFromImap = function(callback) {
|
||||
|
||||
// fetch list from imap server
|
||||
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) {
|
||||
return done(err);
|
||||
}
|
||||
@ -1355,52 +1360,80 @@ EmailDAO.prototype._initFoldersFromImap = function(callback) {
|
||||
// initialize the folders to something meaningful if that hasn't already happened
|
||||
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] = [{
|
||||
name: config.outboxMailboxName,
|
||||
type: config.outboxMailboxType,
|
||||
path: config.outboxMailboxPath
|
||||
}];
|
||||
|
||||
// indicates if we need to persist anything to disk
|
||||
var foldersChanged = false;
|
||||
// aggregate all of the imap folders in one place
|
||||
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
|
||||
[FOLDER_TYPE_INBOX, FOLDER_TYPE_SENT, config.outboxMailboxType, FOLDER_TYPE_DRAFTS, FOLDER_TYPE_TRASH].forEach(function(mbxType) {
|
||||
var localFolderWithType, imapFolderWithPath;
|
||||
// find out all the imap paths that are new/removed
|
||||
var imapFolderPaths = _.pluck(imapFolders, 'path'),
|
||||
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
|
||||
localFolderWithType = _.findWhere(self._account.folders, {
|
||||
type: mbxType
|
||||
// folders need updating if there are new/removed 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 (localFolderWithType) {
|
||||
// we have a local folder available, so let's check if this folder still exists on imap
|
||||
|
||||
imapFolderWithPath = _.findWhere(wellKnownFolders[mbxType], {
|
||||
path: localFolderWithType.path
|
||||
});
|
||||
|
||||
if (imapFolderWithPath) {
|
||||
// folder present on imap, no need to update.
|
||||
return;
|
||||
}
|
||||
|
||||
// folder not present on imap, so remove the folder and see if there are any updates for this folder type
|
||||
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
|
||||
if (wellknownFolder) {
|
||||
// well known folder found, no need to find a replacement
|
||||
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]);
|
||||
// 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
|
||||
});
|
||||
|
||||
if (!wellknownFolder) {
|
||||
// no folder of that type, to mark as well known, nothing to do here
|
||||
return;
|
||||
}
|
||||
|
||||
wellknownFolder.wellknown = true;
|
||||
foldersChanged = true;
|
||||
});
|
||||
|
||||
@ -1415,9 +1448,11 @@ EmailDAO.prototype._initFoldersFromImap = function(callback) {
|
||||
return {
|
||||
name: folder.name,
|
||||
path: folder.path,
|
||||
type: folder.type
|
||||
type: folder.type,
|
||||
wellknown: !!folder.wellknown
|
||||
};
|
||||
});
|
||||
|
||||
self._devicestorage.storeList([folders], FOLDER_DB_TYPE, function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
|
@ -6,7 +6,7 @@
|
||||
<ul class="nav-primary">
|
||||
<li ng-repeat="folder in account.folders" ng-switch="folder.count !== undefined && folder.count > 0">
|
||||
<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 label-light">{{folder.count}}</span>
|
||||
</span>
|
||||
|
@ -25,7 +25,7 @@ describe('Email DAO unit tests', function() {
|
||||
var emailAddress, passphrase, asymKeySize, account;
|
||||
|
||||
// test data
|
||||
var folders, inboxFolder, sentFolder, draftsFolder, outboxFolder, trashFolder, mockKeyPair;
|
||||
var folders, inboxFolder, sentFolder, draftsFolder, outboxFolder, trashFolder, otherFolder, mockKeyPair;
|
||||
|
||||
beforeEach(function() {
|
||||
//
|
||||
@ -70,7 +70,14 @@ describe('Email DAO unit tests', function() {
|
||||
messages: []
|
||||
};
|
||||
|
||||
folders = [inboxFolder, outboxFolder, trashFolder, sentFolder];
|
||||
otherFolder = {
|
||||
name: 'Other',
|
||||
type: 'Other',
|
||||
path: 'OTHER',
|
||||
messages: []
|
||||
};
|
||||
|
||||
folders = [inboxFolder, outboxFolder, trashFolder, sentFolder, otherFolder];
|
||||
|
||||
account = {
|
||||
emailAddress: emailAddress,
|
||||
@ -1995,7 +2002,8 @@ describe('Email DAO unit tests', function() {
|
||||
Inbox: [inboxFolder],
|
||||
Sent: [sentFolder],
|
||||
Drafts: [draftsFolder],
|
||||
Trash: [trashFolder]
|
||||
Trash: [trashFolder],
|
||||
Other: [otherFolder]
|
||||
});
|
||||
devicestorageStub.storeList.withArgs(sinon.match(function(arg) {
|
||||
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].path).to.deep.equal(sentFolder.path);
|
||||
expect(arg[0][1].type).to.deep.equal(sentFolder.type);
|
||||
expect(arg[0][2].name).to.deep.equal(outboxFolder.name);
|
||||
expect(arg[0][2].path).to.deep.equal(outboxFolder.path);
|
||||
expect(arg[0][2].type).to.deep.equal(outboxFolder.type);
|
||||
expect(arg[0][3].name).to.deep.equal(draftsFolder.name);
|
||||
expect(arg[0][3].path).to.deep.equal(draftsFolder.path);
|
||||
expect(arg[0][3].type).to.deep.equal(draftsFolder.type);
|
||||
expect(arg[0][4].name).to.deep.equal(trashFolder.name);
|
||||
expect(arg[0][4].path).to.deep.equal(trashFolder.path);
|
||||
expect(arg[0][4].type).to.deep.equal(trashFolder.type);
|
||||
expect(arg[0][2].name).to.deep.equal(draftsFolder.name);
|
||||
expect(arg[0][2].path).to.deep.equal(draftsFolder.path);
|
||||
expect(arg[0][2].type).to.deep.equal(draftsFolder.type);
|
||||
expect(arg[0][3].name).to.deep.equal(trashFolder.name);
|
||||
expect(arg[0][3].path).to.deep.equal(trashFolder.path);
|
||||
expect(arg[0][3].type).to.deep.equal(trashFolder.type);
|
||||
expect(arg[0][4].name).to.deep.equal(otherFolder.name);
|
||||
expect(arg[0][4].path).to.deep.equal(otherFolder.path);
|
||||
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;
|
||||
}), 'folders').yieldsAsync();
|
||||
|
||||
@ -2037,29 +2048,40 @@ describe('Email DAO unit tests', function() {
|
||||
Inbox: [inboxFolder],
|
||||
Sent: [sentFolder],
|
||||
Drafts: [draftsFolder],
|
||||
Trash: [trashFolder]
|
||||
Trash: [trashFolder],
|
||||
Other: [otherFolder]
|
||||
});
|
||||
devicestorageStub.storeList.withArgs(sinon.match(function(arg) {
|
||||
expect(arg[0]).to.deep.equal([{
|
||||
name: inboxFolder.name,
|
||||
path: inboxFolder.path,
|
||||
type: inboxFolder.type
|
||||
type: inboxFolder.type,
|
||||
wellknown: true
|
||||
}, {
|
||||
name: outboxFolder.name,
|
||||
path: outboxFolder.path,
|
||||
type: outboxFolder.type
|
||||
type: outboxFolder.type,
|
||||
wellknown: true
|
||||
}, {
|
||||
name: trashFolder.name,
|
||||
path: trashFolder.path,
|
||||
type: trashFolder.type
|
||||
type: trashFolder.type,
|
||||
wellknown: true
|
||||
}, {
|
||||
name: sentFolder.name,
|
||||
path: sentFolder.path,
|
||||
type: sentFolder.type
|
||||
type: sentFolder.type,
|
||||
wellknown: true
|
||||
}, {
|
||||
name: draftsFolder.name,
|
||||
path: draftsFolder.path,
|
||||
type: draftsFolder.type
|
||||
type: draftsFolder.type,
|
||||
wellknown: true
|
||||
}, {
|
||||
name: otherFolder.name,
|
||||
path: otherFolder.path,
|
||||
type: otherFolder.type,
|
||||
wellknown: false
|
||||
}]);
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user