2014-10-02 16:05:44 -04:00
|
|
|
'use strict';
|
2013-09-11 16:11:26 -04:00
|
|
|
|
2014-11-26 07:43:10 -05:00
|
|
|
var util = require('crypto-lib').util;
|
2014-10-02 16:05:44 -04:00
|
|
|
|
|
|
|
//
|
|
|
|
// Controller
|
|
|
|
//
|
|
|
|
|
2014-12-05 11:02:19 -05:00
|
|
|
var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain, pgp, email, outbox, dialog, axe, status) {
|
2014-11-20 09:14:39 -05:00
|
|
|
|
|
|
|
var str = appConfig.string;
|
2014-11-25 11:45:22 -05:00
|
|
|
var cfg = appConfig.config;
|
2014-10-02 16:05:44 -04:00
|
|
|
|
|
|
|
// set default value so that the popover height is correct on init
|
|
|
|
$scope.keyId = 'XXXXXXXX';
|
2013-09-13 08:11:47 -04:00
|
|
|
|
|
|
|
//
|
2014-10-02 16:05:44 -04:00
|
|
|
// Init
|
2013-09-13 08:11:47 -04:00
|
|
|
//
|
2013-09-12 11:22:17 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.state.writer = {
|
|
|
|
write: function(replyTo, replyAll, forward) {
|
|
|
|
$scope.state.lightbox = 'write';
|
|
|
|
$scope.replyTo = replyTo;
|
|
|
|
|
|
|
|
resetFields();
|
|
|
|
|
|
|
|
// fill fields depending on replyTo
|
|
|
|
fillFields(replyTo, replyAll, forward);
|
|
|
|
|
|
|
|
$scope.verify($scope.to[0]);
|
|
|
|
},
|
|
|
|
reportBug: function() {
|
|
|
|
$scope.state.lightbox = 'write';
|
|
|
|
resetFields();
|
|
|
|
reportBug();
|
|
|
|
$scope.verify($scope.to[0]);
|
|
|
|
},
|
|
|
|
close: function() {
|
|
|
|
$scope.state.lightbox = undefined;
|
2013-10-18 21:32:00 -04:00
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
};
|
2013-10-12 13:39:09 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
function resetFields() {
|
|
|
|
$scope.writerTitle = 'New email';
|
|
|
|
$scope.to = [];
|
|
|
|
$scope.showCC = false;
|
|
|
|
$scope.cc = [];
|
|
|
|
$scope.showBCC = false;
|
|
|
|
$scope.bcc = [];
|
|
|
|
$scope.subject = '';
|
|
|
|
$scope.body = '';
|
|
|
|
$scope.attachments = [];
|
|
|
|
$scope.addressBookCache = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
function reportBug() {
|
|
|
|
var dump = '';
|
|
|
|
var appender = {
|
|
|
|
log: function(level, date, component, log) {
|
|
|
|
// add a tag for the log level
|
|
|
|
if (level === axe.DEBUG) {
|
|
|
|
dump += '[DEBUG]';
|
|
|
|
} else if (level === axe.INFO) {
|
|
|
|
dump += '[INFO]';
|
|
|
|
} else if (level === axe.WARN) {
|
|
|
|
dump += '[WARN]';
|
|
|
|
} else if (level === axe.ERROR) {
|
|
|
|
dump += '[ERROR]';
|
|
|
|
}
|
2014-06-18 11:09:04 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
dump += '[' + date.toISOString() + ']';
|
2014-06-18 11:09:04 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// component is optional
|
|
|
|
if (component) {
|
|
|
|
dump += '[' + component + ']';
|
|
|
|
}
|
2014-06-18 11:09:04 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// log may be an error or a string
|
|
|
|
dump += ' ' + (log || '').toString();
|
2014-06-18 11:09:04 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// if an error it is, a stack trace it has. print it, we should.
|
|
|
|
if (log.stack) {
|
|
|
|
dump += ' . Stack: ' + log.stack;
|
2014-06-18 11:09:04 -04:00
|
|
|
}
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
dump += '\n';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
axe.dump(appender);
|
2014-07-01 13:49:19 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.to = [{
|
|
|
|
address: str.supportAddress
|
|
|
|
}];
|
|
|
|
$scope.writerTitle = str.bugReportTitle;
|
|
|
|
$scope.subject = str.bugReportSubject;
|
2014-11-25 11:45:22 -05:00
|
|
|
$scope.body = str.bugReportBody.replace('{0}', navigator.userAgent).replace('{1}', cfg.appVersion) + dump;
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2013-10-13 07:49:37 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
function fillFields(re, replyAll, forward) {
|
|
|
|
var replyTo, from, sentDate, body;
|
2013-10-12 13:39:09 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if (!re) {
|
|
|
|
return;
|
|
|
|
}
|
2014-04-02 13:47:50 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.writerTitle = (forward) ? 'Forward' : 'Reply';
|
2014-05-21 08:19:18 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
replyTo = re.replyTo && re.replyTo[0] && re.replyTo[0].address || re.from[0].address;
|
2014-07-01 13:49:19 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// fill recipient field and references
|
|
|
|
if (!forward) {
|
|
|
|
$scope.to.unshift({
|
|
|
|
address: replyTo
|
|
|
|
});
|
|
|
|
$scope.to.forEach($scope.verify);
|
|
|
|
|
|
|
|
$scope.references = (re.references || []);
|
|
|
|
if (re.id && $scope.references.indexOf(re.id) < 0) {
|
|
|
|
// references might not exist yet, so use the double concat
|
|
|
|
$scope.references = $scope.references.concat(re.id);
|
2014-04-02 13:47:50 -04:00
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
if (re.id) {
|
|
|
|
$scope.inReplyTo = re.id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (replyAll) {
|
|
|
|
re.to.concat(re.cc).forEach(function(recipient) {
|
2014-11-20 09:14:39 -05:00
|
|
|
var me = auth.emailAddress;
|
2014-10-02 16:05:44 -04:00
|
|
|
if (recipient.address === me && replyTo !== me) {
|
|
|
|
// don't reply to yourself
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$scope.cc.unshift({
|
|
|
|
address: recipient.address
|
2014-04-02 13:47:50 -04:00
|
|
|
});
|
2014-10-02 16:05:44 -04:00
|
|
|
});
|
2014-05-07 14:19:20 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// filter duplicates
|
|
|
|
$scope.cc = _.uniq($scope.cc, function(recipient) {
|
|
|
|
return recipient.address;
|
|
|
|
});
|
|
|
|
$scope.showCC = true;
|
|
|
|
$scope.cc.forEach($scope.verify);
|
|
|
|
}
|
2014-04-02 13:47:50 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// fill attachments and references on forward
|
|
|
|
if (forward) {
|
|
|
|
// create a new array, otherwise removing an attachment will also
|
|
|
|
// remove it from the original in the mail list as a side effect
|
|
|
|
$scope.attachments = [].concat(re.attachments);
|
|
|
|
if (re.id) {
|
|
|
|
$scope.references = [re.id];
|
2014-05-14 11:29:27 -04:00
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2014-05-14 11:29:27 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// fill subject
|
|
|
|
if (forward) {
|
|
|
|
$scope.subject = 'Fwd: ' + re.subject;
|
|
|
|
} else {
|
2015-02-17 07:04:45 -05:00
|
|
|
$scope.subject = re.subject ? 'Re: ' + re.subject.replace('Re: ', '') : '';
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2013-10-12 13:39:09 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// fill text body
|
|
|
|
from = re.from[0].name || replyTo;
|
|
|
|
sentDate = $filter('date')(re.sentDate, 'EEEE, MMM d, yyyy h:mm a');
|
2014-04-02 13:47:50 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
function createString(array) {
|
|
|
|
var str = '';
|
|
|
|
array.forEach(function(to) {
|
|
|
|
str += (str) ? ', ' : '';
|
|
|
|
str += ((to.name) ? to.name : to.address) + ' <' + to.address + '>';
|
|
|
|
});
|
|
|
|
return str;
|
|
|
|
}
|
2014-04-02 13:47:50 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if (forward) {
|
|
|
|
body = '\n\n' +
|
|
|
|
'---------- Forwarded message ----------\n' +
|
|
|
|
'From: ' + re.from[0].name + ' <' + re.from[0].address + '>\n' +
|
|
|
|
'Date: ' + sentDate + '\n' +
|
|
|
|
'Subject: ' + re.subject + '\n' +
|
|
|
|
'To: ' + createString(re.to) + '\n' +
|
|
|
|
((re.cc && re.cc.length > 0) ? 'Cc: ' + createString(re.cc) + '\n' : '') +
|
|
|
|
'\n\n';
|
|
|
|
|
|
|
|
} else {
|
|
|
|
body = '\n\n' + sentDate + ' ' + from + ' wrote:\n> ';
|
|
|
|
}
|
2013-11-06 02:36:22 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if (re.body) {
|
|
|
|
body += re.body.trim().split('\n').join('\n> ').replace(/ >/g, '>');
|
|
|
|
$scope.body = body;
|
2013-10-12 13:39:09 -04:00
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2013-10-12 13:39:09 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
//
|
|
|
|
// Editing headers
|
|
|
|
//
|
2013-11-04 15:07:32 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
/**
|
|
|
|
* Verify email address and fetch its public key
|
|
|
|
*/
|
|
|
|
$scope.verify = function(recipient) {
|
|
|
|
if (!recipient) {
|
|
|
|
return;
|
|
|
|
}
|
2014-09-15 10:56:25 -04:00
|
|
|
|
2015-01-28 09:01:18 -05:00
|
|
|
if (recipient.address) {
|
|
|
|
// display only email address after autocomplete
|
|
|
|
recipient.displayId = recipient.address;
|
|
|
|
} else {
|
|
|
|
// set address after manual input
|
|
|
|
recipient.address = recipient.displayId;
|
|
|
|
}
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// set display to insecure while fetching keys
|
|
|
|
recipient.key = undefined;
|
|
|
|
recipient.secure = false;
|
|
|
|
$scope.checkSendStatus();
|
|
|
|
|
|
|
|
// verify email address
|
|
|
|
if (!util.validateEmailAddress(recipient.address)) {
|
|
|
|
recipient.secure = undefined;
|
2014-02-28 07:50:00 -05:00
|
|
|
$scope.checkSendStatus();
|
2014-10-02 16:05:44 -04:00
|
|
|
return;
|
|
|
|
}
|
2014-01-10 15:35:34 -05:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
// check if to address is contained in known public keys
|
|
|
|
// when we write an email, we always need to work with the latest keys available
|
|
|
|
return $q(function(resolve) {
|
|
|
|
resolve();
|
|
|
|
|
|
|
|
}).then(function() {
|
|
|
|
return keychain.refreshKeyForUserId({
|
2014-11-06 08:28:14 -05:00
|
|
|
userId: recipient.address
|
2014-12-17 12:18:26 -05:00
|
|
|
});
|
2014-01-10 15:35:34 -05:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).then(function(key) {
|
|
|
|
if (key) {
|
|
|
|
// compare again since model could have changed during the roundtrip
|
2015-01-28 09:01:18 -05:00
|
|
|
var userIds = pgp.getKeyParams(key.publicKey).userIds;
|
|
|
|
var matchingUserId = _.findWhere(userIds, {
|
2014-12-17 12:18:26 -05:00
|
|
|
emailAddress: recipient.address
|
|
|
|
});
|
|
|
|
// compare either primary userId or (if available) multiple IDs
|
2015-01-28 09:01:18 -05:00
|
|
|
if (matchingUserId) {
|
2014-12-17 12:18:26 -05:00
|
|
|
recipient.key = key;
|
|
|
|
recipient.secure = true;
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2014-12-17 12:18:26 -05:00
|
|
|
}
|
|
|
|
$scope.checkSendStatus();
|
2014-01-13 17:54:53 -05:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).catch(dialog.error);
|
2014-10-02 16:05:44 -04:00
|
|
|
};
|
2014-01-19 10:58:51 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
/**
|
|
|
|
* Check if it is ok to send an email depending on the invitation state of the addresses
|
|
|
|
*/
|
|
|
|
$scope.checkSendStatus = function() {
|
|
|
|
$scope.okToSend = false;
|
|
|
|
$scope.sendBtnText = undefined;
|
|
|
|
$scope.sendBtnSecure = undefined;
|
2014-01-19 10:58:51 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
var allSecure = true;
|
|
|
|
var numReceivers = 0;
|
|
|
|
|
|
|
|
// count number of receivers and check security
|
|
|
|
$scope.to.forEach(check);
|
|
|
|
$scope.cc.forEach(check);
|
|
|
|
$scope.bcc.forEach(check);
|
2013-11-04 15:07:32 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
function check(recipient) {
|
|
|
|
// validate address
|
|
|
|
if (!util.validateEmailAddress(recipient.address)) {
|
2015-01-28 09:01:18 -05:00
|
|
|
return dialog.info({
|
|
|
|
title: 'Warning',
|
|
|
|
message: 'Invalid recipient address!'
|
|
|
|
});
|
2014-02-27 09:23:33 -05:00
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
numReceivers++;
|
|
|
|
if (!recipient.secure) {
|
2014-05-16 07:09:55 -04:00
|
|
|
allSecure = false;
|
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2014-05-16 07:09:55 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// only allow sending if receviers exist
|
|
|
|
if (numReceivers < 1) {
|
|
|
|
return;
|
|
|
|
}
|
2013-11-04 15:07:32 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// bcc automatically disables secure sending
|
|
|
|
if ($scope.bcc.filter(filterEmptyAddresses).length > 0) {
|
|
|
|
allSecure = false;
|
|
|
|
}
|
2014-02-05 18:41:08 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if (allSecure) {
|
|
|
|
// send encrypted if all secure
|
|
|
|
$scope.okToSend = true;
|
|
|
|
$scope.sendBtnText = str.sendBtnSecure;
|
|
|
|
$scope.sendBtnSecure = true;
|
|
|
|
} else {
|
|
|
|
// send plaintext
|
|
|
|
$scope.okToSend = true;
|
|
|
|
$scope.sendBtnText = str.sendBtnClear;
|
|
|
|
$scope.sendBtnSecure = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Editing attachments
|
|
|
|
//
|
|
|
|
|
|
|
|
$scope.remove = function(attachment) {
|
|
|
|
$scope.attachments.splice($scope.attachments.indexOf(attachment), 1);
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Editing email body
|
|
|
|
//
|
|
|
|
|
|
|
|
$scope.sendToOutbox = function() {
|
2014-11-20 09:14:39 -05:00
|
|
|
var message;
|
2014-10-02 16:05:44 -04:00
|
|
|
|
|
|
|
// build email model for smtp-client
|
2014-11-20 09:14:39 -05:00
|
|
|
message = {
|
2014-10-02 16:05:44 -04:00
|
|
|
from: [{
|
2014-11-20 09:14:39 -05:00
|
|
|
name: auth.realname,
|
|
|
|
address: auth.emailAddress
|
2014-10-02 16:05:44 -04:00
|
|
|
}],
|
|
|
|
to: $scope.to.filter(filterEmptyAddresses),
|
|
|
|
cc: $scope.cc.filter(filterEmptyAddresses),
|
|
|
|
bcc: $scope.bcc.filter(filterEmptyAddresses),
|
|
|
|
subject: $scope.subject.trim() ? $scope.subject.trim() : str.fallbackSubject, // Subject line, or the fallback subject, if nothing valid was entered
|
|
|
|
body: $scope.body.trim(), // use parsed plaintext body
|
|
|
|
attachments: $scope.attachments,
|
|
|
|
sentDate: new Date(),
|
|
|
|
headers: {}
|
2014-02-05 18:41:08 -05:00
|
|
|
};
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if ($scope.inReplyTo) {
|
2014-11-20 09:14:39 -05:00
|
|
|
message.headers['in-reply-to'] = '<' + $scope.inReplyTo + '>';
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
2014-01-13 12:38:45 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if ($scope.references && $scope.references.length) {
|
2014-11-20 09:14:39 -05:00
|
|
|
message.headers.references = $scope.references.map(function(reference) {
|
2014-10-02 16:05:44 -04:00
|
|
|
return '<' + reference + '>';
|
|
|
|
}).join(' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
// close the writer
|
|
|
|
$scope.state.writer.close();
|
2014-12-05 11:02:19 -05:00
|
|
|
// close read mode after reply
|
|
|
|
if ($scope.replyTo) {
|
|
|
|
status.setReading(false);
|
|
|
|
}
|
2014-05-21 08:19:18 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
// persist the email to disk for later sending
|
2014-12-17 12:18:26 -05:00
|
|
|
return $q(function(resolve) {
|
|
|
|
resolve();
|
2014-05-21 08:19:18 -04:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).then(function() {
|
|
|
|
return outbox.put(message);
|
|
|
|
|
|
|
|
}).then(function() {
|
2014-10-02 16:05:44 -04:00
|
|
|
// if we need to synchronize replyTo.answered = true to imap,
|
|
|
|
// let's do that. otherwise, we're done
|
|
|
|
if (!$scope.replyTo || $scope.replyTo.answered) {
|
|
|
|
return;
|
|
|
|
}
|
2014-02-25 15:05:59 -05:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.replyTo.answered = true;
|
2014-12-17 12:18:26 -05:00
|
|
|
return email.setFlags({
|
2014-10-02 16:05:44 -04:00
|
|
|
folder: currentFolder(),
|
|
|
|
message: $scope.replyTo
|
2013-12-09 13:21:52 -05:00
|
|
|
});
|
2014-02-25 08:10:55 -05:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).catch(function(err) {
|
|
|
|
if (err.code !== 42) {
|
|
|
|
dialog.error(err);
|
|
|
|
}
|
|
|
|
});
|
2014-10-02 16:05:44 -04:00
|
|
|
};
|
2013-09-11 16:11:26 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
//
|
|
|
|
// Tag input & Autocomplete
|
|
|
|
//
|
2014-09-15 10:56:25 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.tagStyle = function(recipient) {
|
|
|
|
var classes = ['label'];
|
|
|
|
if (recipient.secure === false) {
|
2014-09-23 09:41:37 -04:00
|
|
|
classes.push('label--invalid');
|
2014-10-02 16:05:44 -04:00
|
|
|
}
|
|
|
|
return classes;
|
|
|
|
};
|
2014-09-15 10:56:25 -04:00
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.lookupAddressBook = function(query) {
|
2014-12-17 12:18:26 -05:00
|
|
|
return $q(function(resolve) {
|
|
|
|
resolve();
|
2014-09-15 10:56:25 -04:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).then(function() {
|
|
|
|
if ($scope.addressBookCache) {
|
|
|
|
return;
|
|
|
|
}
|
2014-10-02 16:05:44 -04:00
|
|
|
// populate address book cache
|
2014-12-17 12:18:26 -05:00
|
|
|
return keychain.listLocalPublicKeys().then(function(keys) {
|
2014-10-02 16:05:44 -04:00
|
|
|
$scope.addressBookCache = keys.map(function(key) {
|
2015-01-28 09:01:18 -05:00
|
|
|
var name = pgp.getKeyParams(key.publicKey).userIds[0].name;
|
2014-10-02 16:05:44 -04:00
|
|
|
return {
|
2015-01-28 09:01:18 -05:00
|
|
|
address: key.userId,
|
|
|
|
displayId: name + ' - ' + key.userId
|
2014-10-02 16:05:44 -04:00
|
|
|
};
|
2014-09-15 13:06:31 -04:00
|
|
|
});
|
2014-10-02 16:05:44 -04:00
|
|
|
});
|
2014-05-21 08:19:18 -04:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).then(function() {
|
|
|
|
// filter the address book cache
|
|
|
|
return $scope.addressBookCache.filter(function(i) {
|
2015-01-28 09:01:18 -05:00
|
|
|
return i.displayId.toLowerCase().indexOf(query.toLowerCase()) !== -1;
|
2014-10-02 16:05:44 -04:00
|
|
|
});
|
2014-05-16 07:09:55 -04:00
|
|
|
|
2014-12-17 12:18:26 -05:00
|
|
|
}).catch(dialog.error);
|
2014-10-02 16:05:44 -04:00
|
|
|
};
|
2014-05-16 07:09:55 -04:00
|
|
|
|
2013-09-13 08:11:47 -04:00
|
|
|
//
|
2014-10-02 16:05:44 -04:00
|
|
|
// Helpers
|
2013-09-13 08:11:47 -04:00
|
|
|
//
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
function currentFolder() {
|
|
|
|
return $scope.state.nav.currentFolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Visitor to filter out objects without an address property, i.e. empty addresses
|
|
|
|
*/
|
|
|
|
function filterEmptyAddresses(addr) {
|
|
|
|
return !!addr.address;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-10-08 06:34:34 -04:00
|
|
|
module.exports = WriteCtrl;
|