mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 08:52:15 -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_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;
|
||||||
type: mbxType
|
|
||||||
|
// 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) {
|
if (wellknownFolder) {
|
||||||
// we have a local folder available, so let's check if this folder still exists on imap
|
// well known folder found, no need to find a replacement
|
||||||
|
|
||||||
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
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// we have no folder of the respective type marked as wellknown, so find the
|
||||||
* we have no local folder of the type, so do something intelligent,
|
// next best folder of the respective type and flag it as wellknown so that
|
||||||
* i.e. take the first folder of the respective type
|
// we can display it properly
|
||||||
*/
|
wellknownFolder = _.findWhere(self._account.folders, {
|
||||||
self._account.folders.push(wellKnownFolders[mbxType][0]);
|
type: mbxType
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!wellknownFolder) {
|
||||||
|
// no folder of that type, to mark as well known, nothing to do here
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wellknownFolder.wellknown = true;
|
||||||
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);
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user