diff --git a/src/js/controller/mail-list.js b/src/js/controller/mail-list.js index 3ea7d3d..0783ac6 100644 --- a/src/js/controller/mail-list.js +++ b/src/js/controller/mail-list.js @@ -18,7 +18,7 @@ define(function(require) { // scope functions // - $scope.select = function(email) { + $scope.$parent.select = $scope.select = function(email) { if (!email) { return; } @@ -66,7 +66,7 @@ define(function(require) { // development... display dummy mail objects updateStatus('Last update: ', new Date()); - $scope.emails = createDummyMails(); + $scope.$parent.emails = $scope.emails = createDummyMails(); $scope.select($scope.emails[0]); }); @@ -151,7 +151,7 @@ define(function(require) { return -e.uid; }); - $scope.emails = emails; + $scope.$parent.emails = $scope.emails = emails; $scope.select($scope.emails[0]); $scope.$apply(); } diff --git a/src/js/controller/navigation.js b/src/js/controller/navigation.js index fd2e65c..c73de73 100644 --- a/src/js/controller/navigation.js +++ b/src/js/controller/navigation.js @@ -3,6 +3,7 @@ define(function(require) { var angular = require('angular'), appController = require('js/app-controller'), + _ = require('underscore'), emailDao; // @@ -31,6 +32,49 @@ define(function(require) { $scope.closeNav(); }; + $scope.remove = function(email) { + var trashFolder = _.findWhere($scope.folders, { + type: 'Trash' + }); + + if ($scope.currentFolder === trashFolder) { + emailDao.imapDeleteMessage({ + folder: $scope.currentFolder.path, + uid: email.uid + }, moved); + return; + } + + emailDao.imapMoveMessage({ + folder: $scope.currentFolder.path, + uid: email.uid, + destination: trashFolder.path + }, moved); + + function moved(err) { + var index; + + if (err) { + console.error(err); + return; + } + + index = $scope.emails.indexOf(email); + // show the next mail + if ($scope.emails.length > 1) { + // if we're about to delete the last entry of the array, show the previous (i.e. the one below in the list), + // otherwise show the next one (i.e. the one above in the list) + $scope.select(_.last($scope.emails) === email ? $scope.emails[index - 1] : $scope.emails[index + 1]); + } else { + // if we have only one email in the array, show nothing + $scope.select(); + $scope.selected = undefined; + } + $scope.emails.splice(index, 1); + $scope.$apply(); + } + }; + $scope.write = function(replyTo) { var replyToPath = (replyTo) ? encodeURIComponent($scope.currentFolder.path) + '/' + replyTo.uid : '', url = 'chrome.html#/write/' + replyToPath; diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index 65712fb..c67a703 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -290,14 +290,6 @@ define(function(require) { var self = this, dbType = 'email_' + options.folder; - // validate options - if (!options.folder || typeof options.offset === 'undefined' || typeof options.num === 'undefined') { - callback({ - errMsg: 'Invalid options!' - }); - return; - } - fetchList(function(err, emails) { if (err) { callback(err); @@ -386,14 +378,6 @@ define(function(require) { EmailDAO.prototype.imapListMessages = function(options, callback) { var self = this; - // validate options - if (!options.folder || typeof options.offset === 'undefined' || typeof options.num === 'undefined') { - callback({ - errMsg: 'Invalid options!' - }); - return; - } - self._imapClient.listMessages({ path: options.folder, offset: options.offset, @@ -408,44 +392,54 @@ define(function(require) { EmailDAO.prototype.imapGetMessage = function(options, callback) { var self = this; - // validate options - if (!options.folder || !options.uid) { - callback({ - errMsg: 'Invalid options!' - }); - return; - } - - function messageReady(err, gottenMessage) { - if (err || !gottenMessage) { - callback({ - errMsg: 'Error fetching message body!', - err: err - }); - return; - } - - // return message - callback(null, gottenMessage); - } - self._imapClient.getMessagePreview({ path: options.folder, uid: options.uid - }, messageReady); + }, callback); + }; + + EmailDAO.prototype.imapMoveMessage = function(options, callback) { + var self = this; + + self._imapClient.moveMessage({ + path: options.folder, + uid: options.uid, + destination: options.destination + }, moved); + + function moved(err) { + if (err) { + callback(err); + return; + } + + // delete from local db + self._devicestorage.removeList('email_' + options.folder + '_' + options.uid, callback); + } + }; + + EmailDAO.prototype.imapDeleteMessage = function(options, callback) { + var self = this; + + self._imapClient.deleteMessage({ + path: options.folder, + uid: options.uid + }, moved); + + function moved(err) { + if (err) { + callback(err); + return; + } + + // delete from local db + self._devicestorage.removeList('email_' + options.folder + '_' + options.uid, callback); + } }; EmailDAO.prototype.imapMarkMessageRead = function(options, callback) { var self = this; - // validate options - if (!options.folder || !options.uid) { - callback({ - errMsg: 'Invalid options!' - }); - return; - } - self._imapClient.updateFlags({ path: options.folder, uid: options.uid, diff --git a/src/tpl/read.html b/src/tpl/read.html index b74ad83..727d0f2 100644 --- a/src/tpl/read.html +++ b/src/tpl/read.html @@ -1,5 +1,5 @@
- +
diff --git a/test/new-unit/email-dao-test.js b/test/new-unit/email-dao-test.js index 5327304..d4b0292 100644 --- a/test/new-unit/email-dao-test.js +++ b/test/new-unit/email-dao-test.js @@ -302,14 +302,6 @@ define(function(require) { }); describe('IMAP: list messages from folder', function() { - it('should fail due to bad options', function(done) { - emailDao.imapListMessages({}, function(err) { - expect(imapClientStub.listMessages.called).to.be.false; - expect(err).to.exist; - done(); - }); - }); - it('should work', function(done) { imapClientStub.listMessages.yields(); emailDao.imapListMessages({ @@ -325,16 +317,6 @@ define(function(require) { }); describe('IMAP: get message preview', function() { - it('should fail due to bad options', function(done) { - emailDao.imapGetMessage({ - folder: 'INBOX' - }, function(err) { - expect(imapClientStub.getMessagePreview.called).to.be.false; - expect(err).to.exist; - done(); - }); - }); - it('should parse message body without attachement', function(done) { var uid = 415; @@ -385,6 +367,86 @@ define(function(require) { // }); }); + describe('IMAP: move messages', function() { + it('should move messages and remove from local storage', function(done) { + imapClientStub.moveMessage.yields(); + devicestorageStub.removeList.yields(); + + emailDao.imapMoveMessage({ + folder: 'ORIGIN', + uid: 1234, + destination: 'DESTINATION' + }, function(err) { + expect(err).to.not.exist; + expect(imapClientStub.moveMessage.calledWith({ + path: 'ORIGIN', + uid: 1234, + destination: 'DESTINATION' + })).to.be.true; + expect(imapClientStub.moveMessage.calledOnce).to.be.true; + expect(devicestorageStub.removeList.calledOnce).to.be.true; + done(); + }); + }); + + it('should not remove from local storage after imap error', function(done) { + imapClientStub.moveMessage.yields(new Error('tis a silly place...')); + + emailDao.imapMoveMessage({ + folder: 'ORIGIN', + uid: 1234, + destination: 'DESTINATION' + }, function(err) { + expect(err).to.exist; + expect(imapClientStub.moveMessage.calledWith({ + path: 'ORIGIN', + uid: 1234, + destination: 'DESTINATION' + })).to.be.true; + expect(imapClientStub.moveMessage.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('IMAP: delete messages', function() { + it('should delete messages and remove from local storage', function(done) { + imapClientStub.deleteMessage.yields(); + devicestorageStub.removeList.yields(); + + emailDao.imapDeleteMessage({ + folder: 'FOLDAAAA', + uid: 1234 + }, function(err) { + expect(err).to.not.exist; + expect(imapClientStub.deleteMessage.calledWith({ + path: 'FOLDAAAA', + uid: 1234 + })).to.be.true; + expect(imapClientStub.deleteMessage.calledOnce).to.be.true; + expect(devicestorageStub.removeList.calledOnce).to.be.true; + done(); + }); + }); + + it('should not remove from local storage after imap error', function(done) { + imapClientStub.deleteMessage.yields(new Error('tis a silly place...')); + + emailDao.imapDeleteMessage({ + folder: 'FOLDAAAA', + uid: 1234 + }, function(err) { + expect(err).to.exist; + expect(imapClientStub.deleteMessage.calledWith({ + path: 'FOLDAAAA', + uid: 1234 + })).to.be.true; + expect(imapClientStub.deleteMessage.calledOnce).to.be.true; + done(); + }); + }); + }); + describe('IMAP: sync messages to local storage', function() { it('should not list unencrypted messages', function(done) { imapClientStub.listMessages.yields(null, [{