From 445428be263d817ca6b61354c4ee2b9a0e9e7f5e Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Sat, 12 Oct 2013 19:39:09 +0200 Subject: [PATCH] implement reply ui --- src/js/app-controller.js | 10 ++--- src/js/app.js | 6 ++- src/js/controller/navigation.js | 19 +++++--- src/js/controller/write.js | 67 +++++++++++++++++++++++++--- src/js/dao/email-dao.js | 4 +- src/sass/views/_write.scss | 2 +- src/tpl/read.html | 2 +- src/tpl/write.html | 4 +- test/new-unit/app-controller-test.js | 4 +- 9 files changed, 91 insertions(+), 27 deletions(-) diff --git a/src/js/app-controller.js b/src/js/app-controller.js index 5971ba6..5e8c212 100644 --- a/src/js/app-controller.js +++ b/src/js/app-controller.js @@ -41,7 +41,7 @@ define(function(require) { /** * Request an OAuth token from chrome for gmail users */ - self.fetchOAuthToken = function(password, callback) { + self.fetchOAuthToken = function(passphrase, callback) { // get OAuth Token from chrome chrome.identity.getAuthToken({ 'interactive': true @@ -64,8 +64,8 @@ define(function(require) { return; } - // login using the received email address - self.login(emailAddress, password, token, callback); + // init the email dao + self.init(emailAddress, passphrase, token, callback); }); } ); @@ -124,7 +124,7 @@ define(function(require) { /** * Instanciate the mail email data access object and its dependencies. Login to imap on init. */ - self.login = function(userId, password, token, callback) { + self.init = function(userId, passphrase, token, callback) { var auth, imapOptions, smtpOptions, keychain, imapClient, smtpClient, pgp, userStorage; @@ -162,7 +162,7 @@ define(function(require) { emailAddress: userId, asymKeySize: config.asymKeySize }; - self._emailDao.init(account, password, callback); + self._emailDao.init(account, passphrase, callback); }; return self; diff --git a/src/js/app.js b/src/js/app.js index f353bea..7c7a6fd 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -21,7 +21,11 @@ require([ templateUrl: 'tpl/login.html', controller: LoginCtrl }); - $routeProvider.when('/write/:replyToId', { + $routeProvider.when('/write/:folder/:id', { + templateUrl: 'tpl/write.html', + controller: WriteCtrl + }); + $routeProvider.when('/write', { templateUrl: 'tpl/write.html', controller: WriteCtrl }); diff --git a/src/js/controller/navigation.js b/src/js/controller/navigation.js index 4c73a6d..7c2ea15 100644 --- a/src/js/controller/navigation.js +++ b/src/js/controller/navigation.js @@ -27,8 +27,8 @@ define(function(require) { }; $scope.write = function(replyTo) { - var replyToId = (replyTo) ? replyTo.uid : '', - url = 'index.html#/write/' + replyToId; + var replyToPath = (replyTo) ? encodeURIComponent($scope.currentFolder.path) + '/' + replyTo.uid : '', + url = 'index.html#/write/' + replyToPath; if (window.chrome && chrome.app.window) { chrome.app.window.create(url, { @@ -68,15 +68,20 @@ define(function(require) { } callback([{ - type: 'Inbox' + type: 'Inbox', + path: 'INBOX' }, { - type: 'Sent' + type: 'Sent', + path: 'SENT' }, { - type: 'Outbox' + type: 'Outbox', + path: 'OUTBOX' }, { - type: 'Drafts' + type: 'Drafts', + path: 'DRAFTS' }, { - type: 'Trash' + type: 'Trash', + path: 'TRASH' }]); } }; diff --git a/src/js/controller/write.js b/src/js/controller/write.js index 4e645f9..77c5e50 100644 --- a/src/js/controller/write.js +++ b/src/js/controller/write.js @@ -12,9 +12,13 @@ define(function(require) { // Controller // - var WriteCtrl = function($scope) { + var WriteCtrl = function($scope, $routeParams) { $scope.signature = str.signature; + // + // Init + // + // start the main app controller appController.start(function(err) { if (err) { @@ -23,15 +27,18 @@ define(function(require) { } if (window.chrome && chrome.identity) { - login('passphrase', function() { + init('passphrase', function() { emailDao = appController._emailDao; + getReplyTo($routeParams.folder, $routeParams.id, function() { + $scope.$apply(); + }); }); return; } }); - function login(password, callback) { - appController.fetchOAuthToken(password, function(err) { + function init(passphrase, callback) { + appController.fetchOAuthToken(passphrase, function(err) { if (err) { console.error(err); return; @@ -41,6 +48,51 @@ define(function(require) { }); } + function getReplyTo(folder, id, callback) { + if (!folder || !id) { + callback(); + } + + emailDao.listMessages({ + folder: folder + '_' + id + }, function(err, list) { + if (err) { + console.error(err); + return; + } + + if (list.length > 0) { + fillFields(list[0]); + } + callback(); + }); + } + + function fillFields(re) { + if (!re) { + return; + } + + // fille title + $scope.title = 'Reply'; + // fill recipient field + $scope.to = re.from[0].address; + // fill subject + $scope.subject = 'Re: ' + ((re.subject) ? re.subject.replace('Re: ', '') : ''); + + // fill text body + var body = '

' + re.sentDate + ' ' + re.from[0].name + ' <' + re.from[0].address + '>'; + var bodyRows = re.body.split('\n'); + bodyRows.forEach(function(row) { + body += (!re.html) ? '
> ' + row : ''; + }); + $scope.body = body; + } + + // + // Editing + // + // generate key,iv for encryption preview var key = util.random(128), iv = util.random(128); @@ -127,15 +179,15 @@ define(function(require) { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { // view -> model - elm.on('keyup', function() { + elm.on('keyup keydown focus', function() { scope.$apply(function() { ctrl.$setViewValue(elm.html()); }); }); // model -> view - ctrl.$render = function(value) { - elm.html(value); + ctrl.$render = function() { + elm.html(ctrl.$viewValue); }; // load init value from DOM @@ -143,6 +195,7 @@ define(function(require) { } }; }); + ngModule.directive('focusMe', function($timeout) { return { link: function(scope, element) { diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index 2206965..c4390e7 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -191,12 +191,14 @@ define(function(require) { encryptedList = []; // validate options - if (!options.folder || typeof options.offset === 'undefined' || typeof options.num === 'undefined') { + if (!options.folder) { callback({ errMsg: 'Invalid options!' }); return; } + options.offset = (typeof options.offset === 'undefined') ? 0 : options.offset; + options.num = (typeof options.num === 'undefined') ? null : options.num; // fetch items from device storage self._devicestorage.listItems('email_' + options.folder, options.offset, options.num, function(err, emails) { diff --git a/src/sass/views/_write.scss b/src/sass/views/_write.scss index 4b9b9ec..8ad5199 100644 --- a/src/sass/views/_write.scss +++ b/src/sass/views/_write.scss @@ -62,7 +62,7 @@ .body { line-height: 1.5em; - height: 60%; + height: 68%; overflow-y: scroll; *[contentEditable] { diff --git a/src/tpl/read.html b/src/tpl/read.html index 388b48b..b74ad83 100644 --- a/src/tpl/read.html +++ b/src/tpl/read.html @@ -1,6 +1,6 @@
- +
diff --git a/src/tpl/write.html b/src/tpl/write.html index ac8abdf..2ea432d 100644 --- a/src/tpl/write.html +++ b/src/tpl/write.html @@ -1,10 +1,10 @@
-

New Mail

+

{{title || 'New Mail'}}

To: - +

Cc: diff --git a/test/new-unit/app-controller-test.js b/test/new-unit/app-controller-test.js index 2ba952d..a21f9c1 100644 --- a/test/new-unit/app-controller-test.js +++ b/test/new-unit/app-controller-test.js @@ -15,7 +15,7 @@ define(function(require) { describe('App Controller unit tests', function() { beforeEach(function() { - sinon.stub(controller, 'login', function(userId, password, token, callback) { + sinon.stub(controller, 'init', function(userId, password, token, callback) { controller._emailDao = sinon.createStubInstance(EmailDAO); callback(); }); @@ -35,7 +35,7 @@ define(function(require) { }); afterEach(function() { - controller.login.restore(); + controller.init.restore(); $.get.restore(); $.ajax.restore(); window.chrome.identity.getAuthToken.restore();