mirror of
https://github.com/moparisthebest/mail
synced 2024-08-13 16:43:47 -04:00
implement reply ui
This commit is contained in:
parent
378f529184
commit
445428be26
@ -41,7 +41,7 @@ define(function(require) {
|
|||||||
/**
|
/**
|
||||||
* Request an OAuth token from chrome for gmail users
|
* Request an OAuth token from chrome for gmail users
|
||||||
*/
|
*/
|
||||||
self.fetchOAuthToken = function(password, callback) {
|
self.fetchOAuthToken = function(passphrase, callback) {
|
||||||
// get OAuth Token from chrome
|
// get OAuth Token from chrome
|
||||||
chrome.identity.getAuthToken({
|
chrome.identity.getAuthToken({
|
||||||
'interactive': true
|
'interactive': true
|
||||||
@ -64,8 +64,8 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// login using the received email address
|
// init the email dao
|
||||||
self.login(emailAddress, password, token, callback);
|
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.
|
* 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,
|
var auth, imapOptions, smtpOptions,
|
||||||
keychain, imapClient, smtpClient, pgp, userStorage;
|
keychain, imapClient, smtpClient, pgp, userStorage;
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ define(function(require) {
|
|||||||
emailAddress: userId,
|
emailAddress: userId,
|
||||||
asymKeySize: config.asymKeySize
|
asymKeySize: config.asymKeySize
|
||||||
};
|
};
|
||||||
self._emailDao.init(account, password, callback);
|
self._emailDao.init(account, passphrase, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -21,7 +21,11 @@ require([
|
|||||||
templateUrl: 'tpl/login.html',
|
templateUrl: 'tpl/login.html',
|
||||||
controller: LoginCtrl
|
controller: LoginCtrl
|
||||||
});
|
});
|
||||||
$routeProvider.when('/write/:replyToId', {
|
$routeProvider.when('/write/:folder/:id', {
|
||||||
|
templateUrl: 'tpl/write.html',
|
||||||
|
controller: WriteCtrl
|
||||||
|
});
|
||||||
|
$routeProvider.when('/write', {
|
||||||
templateUrl: 'tpl/write.html',
|
templateUrl: 'tpl/write.html',
|
||||||
controller: WriteCtrl
|
controller: WriteCtrl
|
||||||
});
|
});
|
||||||
|
@ -27,8 +27,8 @@ define(function(require) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.write = function(replyTo) {
|
$scope.write = function(replyTo) {
|
||||||
var replyToId = (replyTo) ? replyTo.uid : '',
|
var replyToPath = (replyTo) ? encodeURIComponent($scope.currentFolder.path) + '/' + replyTo.uid : '',
|
||||||
url = 'index.html#/write/' + replyToId;
|
url = 'index.html#/write/' + replyToPath;
|
||||||
|
|
||||||
if (window.chrome && chrome.app.window) {
|
if (window.chrome && chrome.app.window) {
|
||||||
chrome.app.window.create(url, {
|
chrome.app.window.create(url, {
|
||||||
@ -68,15 +68,20 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callback([{
|
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'
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -12,9 +12,13 @@ define(function(require) {
|
|||||||
// Controller
|
// Controller
|
||||||
//
|
//
|
||||||
|
|
||||||
var WriteCtrl = function($scope) {
|
var WriteCtrl = function($scope, $routeParams) {
|
||||||
$scope.signature = str.signature;
|
$scope.signature = str.signature;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init
|
||||||
|
//
|
||||||
|
|
||||||
// start the main app controller
|
// start the main app controller
|
||||||
appController.start(function(err) {
|
appController.start(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -23,15 +27,18 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (window.chrome && chrome.identity) {
|
if (window.chrome && chrome.identity) {
|
||||||
login('passphrase', function() {
|
init('passphrase', function() {
|
||||||
emailDao = appController._emailDao;
|
emailDao = appController._emailDao;
|
||||||
|
getReplyTo($routeParams.folder, $routeParams.id, function() {
|
||||||
|
$scope.$apply();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function login(password, callback) {
|
function init(passphrase, callback) {
|
||||||
appController.fetchOAuthToken(password, function(err) {
|
appController.fetchOAuthToken(passphrase, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return;
|
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 = '<br><br>' + re.sentDate + ' ' + re.from[0].name + ' <' + re.from[0].address + '>';
|
||||||
|
var bodyRows = re.body.split('\n');
|
||||||
|
bodyRows.forEach(function(row) {
|
||||||
|
body += (!re.html) ? '<br> > ' + row : '';
|
||||||
|
});
|
||||||
|
$scope.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Editing
|
||||||
|
//
|
||||||
|
|
||||||
// generate key,iv for encryption preview
|
// generate key,iv for encryption preview
|
||||||
var key = util.random(128),
|
var key = util.random(128),
|
||||||
iv = util.random(128);
|
iv = util.random(128);
|
||||||
@ -127,15 +179,15 @@ define(function(require) {
|
|||||||
require: 'ngModel',
|
require: 'ngModel',
|
||||||
link: function(scope, elm, attrs, ctrl) {
|
link: function(scope, elm, attrs, ctrl) {
|
||||||
// view -> model
|
// view -> model
|
||||||
elm.on('keyup', function() {
|
elm.on('keyup keydown focus', function() {
|
||||||
scope.$apply(function() {
|
scope.$apply(function() {
|
||||||
ctrl.$setViewValue(elm.html());
|
ctrl.$setViewValue(elm.html());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// model -> view
|
// model -> view
|
||||||
ctrl.$render = function(value) {
|
ctrl.$render = function() {
|
||||||
elm.html(value);
|
elm.html(ctrl.$viewValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
// load init value from DOM
|
// load init value from DOM
|
||||||
@ -143,6 +195,7 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
ngModule.directive('focusMe', function($timeout) {
|
ngModule.directive('focusMe', function($timeout) {
|
||||||
return {
|
return {
|
||||||
link: function(scope, element) {
|
link: function(scope, element) {
|
||||||
|
@ -191,12 +191,14 @@ define(function(require) {
|
|||||||
encryptedList = [];
|
encryptedList = [];
|
||||||
|
|
||||||
// validate options
|
// validate options
|
||||||
if (!options.folder || typeof options.offset === 'undefined' || typeof options.num === 'undefined') {
|
if (!options.folder) {
|
||||||
callback({
|
callback({
|
||||||
errMsg: 'Invalid options!'
|
errMsg: 'Invalid options!'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
options.offset = (typeof options.offset === 'undefined') ? 0 : options.offset;
|
||||||
|
options.num = (typeof options.num === 'undefined') ? null : options.num;
|
||||||
|
|
||||||
// fetch items from device storage
|
// fetch items from device storage
|
||||||
self._devicestorage.listItems('email_' + options.folder, options.offset, options.num, function(err, emails) {
|
self._devicestorage.listItems('email_' + options.folder, options.offset, options.num, function(err, emails) {
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
.body {
|
.body {
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
height: 60%;
|
height: 68%;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
*[contentEditable] {
|
*[contentEditable] {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button class="btn-icon"></button>
|
<button class="btn-icon"></button>
|
||||||
<button class="btn-icon"></button>
|
<button ng-click="write(selected)" class="btn-icon"></button>
|
||||||
<button ng-click="write()" class="btn-icon"></button>
|
<button ng-click="write()" class="btn-icon"></button>
|
||||||
</div><!--/.controls-->
|
</div><!--/.controls-->
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<div class="view-write">
|
<div class="view-write">
|
||||||
<p class="title">New Mail</p>
|
<p class="title">{{title || 'New Mail'}}</p>
|
||||||
|
|
||||||
<div class="headers">
|
<div class="headers">
|
||||||
<p>
|
<p>
|
||||||
<span>To:</span>
|
<span>To:</span>
|
||||||
<input type="email" ng-model="to" class="address-input" tabindex="1" focus-me >
|
<input type="email" ng-model="to" class="address-input" tabindex="1" focus-me>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span>Cc:</span>
|
<span>Cc:</span>
|
||||||
|
@ -15,7 +15,7 @@ define(function(require) {
|
|||||||
describe('App Controller unit tests', function() {
|
describe('App Controller unit tests', function() {
|
||||||
|
|
||||||
beforeEach(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);
|
controller._emailDao = sinon.createStubInstance(EmailDAO);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
@ -35,7 +35,7 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
controller.login.restore();
|
controller.init.restore();
|
||||||
$.get.restore();
|
$.get.restore();
|
||||||
$.ajax.restore();
|
$.ajax.restore();
|
||||||
window.chrome.identity.getAuthToken.restore();
|
window.chrome.identity.getAuthToken.restore();
|
||||||
|
Loading…
Reference in New Issue
Block a user