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

Merge pull request #60 from whiteout-io/dev/WO-382

[WO-382] Lazy loading for attachments
This commit is contained in:
Tankred Hase 2014-05-13 16:28:49 +02:00
commit c0a6514a13
4 changed files with 96 additions and 5 deletions

View File

@ -117,7 +117,7 @@ define(function(require) {
var email = $scope.state.mailList.selected; var email = $scope.state.mailList.selected;
emailDao.getAttachment({ emailDao.getAttachment({
path: folder.path, folder: folder.path,
uid: email.uid, uid: email.uid,
attachment: attachment attachment: attachment
}, function(err) { }, function(err) {

View File

@ -306,9 +306,19 @@ define(function(require) {
var localMessage = localMessages[0]; var localMessage = localMessages[0];
// treat attachment and non-attachment body parts separately:
// we need to fetch the content for non-attachment body parts (encrypted, signed, text, html)
// but we spare the effort and fetch attachment content later upon explicit user request.
var contentParts = localMessage.bodyParts.filter(function(bodyPart) {
return bodyPart.type !== "attachment";
});
var attachmentParts = localMessage.bodyParts.filter(function(bodyPart) {
return bodyPart.type === "attachment";
});
// do we need to fetch content from the imap server? // do we need to fetch content from the imap server?
var needsFetch = false; var needsFetch = false;
localMessage.bodyParts.forEach(function(part) { contentParts.forEach(function(part) {
needsFetch = (typeof part.content === 'undefined'); needsFetch = (typeof part.content === 'undefined');
}); });
@ -324,15 +334,16 @@ define(function(require) {
self._emailSync._getBodyParts({ self._emailSync._getBodyParts({
folder: folder, folder: folder,
uid: localMessage.uid, uid: localMessage.uid,
bodyParts: localMessage.bodyParts bodyParts: contentParts
}, function(err, parsedBodyParts) { }, function(err, parsedBodyParts) {
if (err) { if (err) {
done(err); done(err);
return; return;
} }
message.bodyParts = parsedBodyParts; // piece together the parsed bodyparts and the empty attachments which have not been parsed
localMessage.bodyParts = parsedBodyParts; message.bodyParts = parsedBodyParts.concat(attachmentParts);
localMessage.bodyParts = parsedBodyParts.concat(attachmentParts);
// persist it to disk // persist it to disk
self._emailSync._localStoreMessages({ self._emailSync._localStoreMessages({
@ -384,6 +395,22 @@ define(function(require) {
} }
}; };
EmailDAO.prototype.getAttachment = function(options, callback) {
this._emailSync._getBodyParts({
folder: options.folder,
uid: options.uid,
bodyParts: [options.attachment]
}, function(err, parsedBodyParts) {
if (err) {
callback(err);
return;
}
options.attachment.content = parsedBodyParts[0].content;
callback(err, err ? undefined : options.attachment);
});
};
EmailDAO.prototype.decryptBody = function(options, callback) { EmailDAO.prototype.decryptBody = function(options, callback) {
var self = this, var self = this,
message = options.message; message = options.message;

View File

@ -447,6 +447,13 @@ define(function(require) {
return; return;
} }
// this enables us to already show the attachment clip in the message list ui
messages.forEach(function(message) {
message.attachments = message.bodyParts.filter(function(bodyPart) {
return bodyPart.type === 'attachment';
});
});
// if persisting worked, add them to the messages array // if persisting worked, add them to the messages array
folder.messages = folder.messages.concat(messages); folder.messages = folder.messages.concat(messages);
self.onIncomingMessage(messages); self.onIncomingMessage(messages);

View File

@ -866,6 +866,63 @@ define(function(require) {
}); });
}); });
describe('getAttachment', function() {
var folder = 'asdasdasdasdasd',
uid = 1234,
imapGetStub;
beforeEach(function() {
imapGetStub = sinon.stub(emailSync, '_getBodyParts');
});
afterEach(function() {
emailSync._getBodyParts.restore();
});
it('should fetch an attachment from imap', function(done) {
var attmt = {};
imapGetStub.withArgs({
folder: folder,
uid: uid,
bodyParts: [attmt]
}).yieldsAsync(null, [{
content: 'CONTENT!!!'
}]);
dao.getAttachment({
folder: folder,
uid: uid,
attachment: attmt
}, function(err, fetchedAttmt) {
expect(err).to.not.exist;
expect(fetchedAttmt).to.equal(attmt);
expect(attmt.content).to.not.be.empty;
expect(imapGetStub.calledOnce).to.be.true;
done();
});
});
it('should error during fetch', function(done) {
var attmt = {};
imapGetStub.yieldsAsync({});
dao.getAttachment({
folder: folder,
uid: uid,
attachment: attmt
}, function(err, fetchedAttmt) {
expect(err).to.exist;
expect(fetchedAttmt).to.not.exist;
expect(imapGetStub.calledOnce).to.be.true;
done();
});
});
});
describe('decryptBody', function() { describe('decryptBody', function() {
it('should do nothing when the message is not encrypted', function() { it('should do nothing when the message is not encrypted', function() {
var message = { var message = {