Refactor app controllers

This commit is contained in:
Tankred Hase 2014-12-17 18:18:26 +01:00
parent 085b104521
commit eab07041f0
9 changed files with 343 additions and 339 deletions

View File

@ -1,6 +1,6 @@
'use strict';
var AccountCtrl = function($scope, auth, keychain, pgp, appConfig, download, dialog) {
var AccountCtrl = function($scope, $q, auth, keychain, pgp, appConfig, download, dialog) {
var userId = auth.emailAddress;
if (!userId) {
return;
@ -34,12 +34,13 @@ var AccountCtrl = function($scope, auth, keychain, pgp, appConfig, download, dia
//
$scope.exportKeyFile = function() {
keychain.getUserKeyPair(userId, function(err, keys) {
if (err) {
dialog.error(err);
return;
}
return $q(function(resolve) {
resolve();
}).then(function() {
return keychain.getUserKeyPair(userId);
}).then(function(keys) {
var keyId = keys.publicKey._id;
var file = 'whiteout_mail_' + userId + '_' + keyId.substring(8, keyId.length);
@ -48,7 +49,8 @@ var AccountCtrl = function($scope, auth, keychain, pgp, appConfig, download, dia
filename: file + '.asc',
contentType: 'text/plain'
});
});
}).catch(dialog.error);
};
};

View File

@ -2,7 +2,7 @@
var JUNK_FOLDER_TYPE = 'Junk';
var ActionBarCtrl = function($scope, email, dialog, status) {
var ActionBarCtrl = function($scope, $q, email, dialog, status) {
//
// scope functions
@ -23,24 +23,28 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
// show message
status.update('Moving message...');
email.moveMessage({
folder: currentFolder(),
destination: destination,
message: message
}, function(err) {
if (err) {
// show errors where appropriate
if (err.code === 42) {
$scope.select(message);
status.update('Unable to move message in offline mode!');
return;
}
status.update('Error during move!');
dialog.error(err);
return $q(function(resolve) {
resolve();
}).then(function() {
return email.moveMessage({
folder: currentFolder(),
destination: destination,
message: message
});
}).then(function() {
status.update('Online');
}).catch(function(err) {
// show errors where appropriate
if (err.code === 42) {
$scope.select(message);
status.update('Unable to move message in offline mode!');
return;
}
status.update('Message moved.');
$scope.$apply();
status.update('Error during move!');
return dialog.error(err);
});
};
@ -83,23 +87,27 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
status.setReading(false);
status.update('Deleting message...');
email.deleteMessage({
folder: currentFolder(),
message: message
}, function(err) {
if (err) {
// show errors where appropriate
if (err.code === 42) {
$scope.select(message);
status.update('Unable to delete message in offline mode!');
return;
}
status.update('Error during delete!');
dialog.error(err);
return $q(function(resolve) {
resolve();
}).then(function() {
return email.deleteMessage({
folder: currentFolder(),
message: message
});
}).then(function() {
status.update('Online');
}).catch(function(err) {
// show errors where appropriate
if (err.code === 42) {
$scope.select(message);
status.update('Unable to delete message in offline mode!');
return;
}
status.update('Message deleted.');
$scope.$apply();
status.update('Error during delete!');
return dialog.error(err);
});
};
@ -130,25 +138,29 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
var originalState = message.unread;
message.unread = unread;
email.setFlags({
folder: currentFolder(),
message: message
}, function(err) {
if (err && err.code === 42) {
return $q(function(resolve) {
resolve();
}).then(function() {
return email.setFlags({
folder: currentFolder(),
message: message
});
}).then(function() {
status.update('Online');
}).catch(function(err) {
if (err.code === 42) {
// offline, restore
message.unread = originalState;
status.update('Unable to mark message in offline mode!');
return;
}
if (err) {
status.update('Error on sync!');
dialog.error(err);
return;
}
status.update('Online');
$scope.$apply();
status.update('Error on sync!');
return dialog.error(err);
});
};
@ -176,25 +188,29 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
var originalState = message.flagged;
message.flagged = flagged;
email.setFlags({
folder: currentFolder(),
message: message
}, function(err) {
if (err && err.code === 42) {
return $q(function(resolve) {
resolve();
}).then(function() {
return email.setFlags({
folder: currentFolder(),
message: message
});
}).then(function() {
status.update('Online');
}).catch(function(err) {
if (err.code === 42) {
// offline, restore
message.unread = originalState;
status.update('Unable to ' + (flagged ? 'add star to' : 'remove star from') + ' message in offline mode!');
return;
}
if (err) {
status.update('Error on sync!');
dialog.error(err);
return;
}
status.update('Online');
$scope.$apply();
status.update('Error on sync!');
return dialog.error(err);
});
};
@ -208,12 +224,27 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
});
};
/**
* This method is called when the user changes the searchText
*/
$scope.displaySearchResults = function(searchText) {
$scope.$root.$broadcast('search', searchText);
};
//
// scope state
//
// share local scope functions with root state
$scope.state.actionBar = {
markMessage: $scope.markMessage,
flagMessage: $scope.flagMessage
};
//
// Helper functions
//
function currentFolder() {
return $scope.state.nav.currentFolder;
}
@ -223,13 +254,6 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
return message.checked;
});
}
/**
* This method is called when the user changes the searchText
*/
$scope.displaySearchResults = function(searchText) {
$scope.$root.$broadcast('search', searchText);
};
};
module.exports = ActionBarCtrl;

View File

@ -4,7 +4,7 @@
// Controller
//
var ContactsCtrl = function($scope, keychain, pgp, dialog) {
var ContactsCtrl = function($scope, $q, keychain, pgp, dialog) {
//
// scope state
@ -13,7 +13,7 @@ var ContactsCtrl = function($scope, keychain, pgp, dialog) {
$scope.state.contacts = {
toggle: function(to) {
$scope.state.lightbox = (to) ? 'contacts' : undefined;
$scope.listKeys();
return $scope.listKeys();
}
};
@ -22,22 +22,21 @@ var ContactsCtrl = function($scope, keychain, pgp, dialog) {
//
$scope.listKeys = function() {
keychain.listLocalPublicKeys(function(err, keys) {
if (err) {
dialog.error(err);
return;
}
return $q(function(resolve) {
resolve();
keys.forEach(addParams);
}).then(function() {
return keychain.listLocalPublicKeys();
$scope.keys = keys;
$scope.$apply();
function addParams(key) {
}).then(function(keys) {
// add params to key objects
keys.forEach(function(key) {
var params = pgp.getKeyParams(key.publicKey);
_.extend(key, params);
}
});
});
$scope.keys = keys;
}).catch(dialog.error);
};
$scope.getFingerprint = function(key) {
@ -74,27 +73,17 @@ var ContactsCtrl = function($scope, keychain, pgp, dialog) {
imported: true // mark manually imported keys
};
keychain.saveLocalPublicKey(pubkey, function(err) {
if (err) {
dialog.error(err);
return;
}
return keychain.saveLocalPublicKey(pubkey).then(function() {
// update displayed keys
$scope.listKeys();
});
return $scope.listKeys();
}).catch(dialog.error);
};
$scope.removeKey = function(key) {
keychain.removeLocalPublicKey(key._id, function(err) {
if (err) {
dialog.error(err);
return;
}
return keychain.removeLocalPublicKey(key._id).then(function() {
// update displayed keys
$scope.listKeys();
});
return $scope.listKeys();
}).catch(dialog.error);
};
};

View File

@ -11,7 +11,7 @@ var INIT_DISPLAY_LEN = 50,
FOLDER_TYPE_INBOX = 'Inbox',
NOTIFICATION_INBOX_TIMEOUT = 5000;
var MailListCtrl = function($scope, $timeout, $location, $filter, status, notification, email, keychain, dialog, search, dummy) {
var MailListCtrl = function($scope, $timeout, $location, $filter, $q, status, notification, email, keychain, dialog, search, dummy) {
//
// scope state
@ -55,23 +55,26 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
//
$scope.getBody = function(message) {
email.getBody({
folder: currentFolder(),
message: message
}, function(err) {
if (err && err.code !== 42) {
dialog.error(err);
return;
}
return $q(function(resolve) {
resolve();
// display fetched body
$scope.$digest();
}).then(function() {
return email.getBody({
folder: currentFolder(),
message: message
});
}).then(function() {
// automatically decrypt if it's the selected message
if (message === currentMessage()) {
email.decryptBody({
return email.decryptBody({
message: message
}, dialog.error);
});
}
}).catch(function(err) {
if (err.code !== 42) {
dialog.error(err);
}
});
};
@ -93,19 +96,20 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
return;
}
keychain.refreshKeyForUserId({
userId: message.from[0].address
}, onKeyRefreshed);
return $q(function(resolve) {
resolve();
function onKeyRefreshed(err) {
if (err) {
dialog.error(err);
}
}).then(function() {
return keychain.refreshKeyForUserId({
userId: message.from[0].address
});
email.decryptBody({
}).then(function() {
return email.decryptBody({
message: message
}, dialog.error);
});
}).then(function() {
// if the message is unread, please sync the new state.
// otherweise forget about it.
if (!message.unread) {
@ -119,12 +123,13 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
}
}
$scope.state.actionBar.markMessage(message, false, true);
}
return $scope.state.actionBar.markMessage(message, false, true);
}).catch(dialog.error);
};
$scope.flag = function(message, flagged) {
$scope.state.actionBar.flagMessage(message, flagged);
return $scope.state.actionBar.flagMessage(message, flagged);
};
/**
@ -164,7 +169,7 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
}
// display and select first
openCurrentFolder();
return openCurrentFolder();
});
$scope.watchMessages = $scope.$watchCollection('state.nav.currentFolder.messages', function(messages) {
@ -246,10 +251,10 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
*/
$scope.watchOnline = $scope.$watch('account.online', function(isOnline) {
// wait one cycle for the status display controllers to init
$timeout(function() {
return $timeout(function() {
if (isOnline) {
status.update('Online');
openCurrentFolder();
return openCurrentFolder();
} else {
status.update('Offline mode');
}
@ -265,18 +270,24 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
return;
}
email.openFolder({
folder: currentFolder()
}, function(error) {
return $q(function(resolve) {
resolve();
}).then(function() {
return email.openFolder({
folder: currentFolder()
}).catch(function(err) {
// don't display err for offline case
if (err.code !== 42) {
throw err;
}
});
}).then(function() {
// dont wait until scroll to load visible mail bodies
$scope.loadVisibleBodies();
// don't display error for offline case
if (error && error.code === 42) {
return;
}
dialog.error(error);
});
}).catch(dialog.error);
}
function currentFolder() {

View File

@ -11,7 +11,7 @@ var NOTIFICATION_SENT_TIMEOUT = 2000;
// Controller
//
var NavigationCtrl = function($scope, $location, account, email, outbox, notification, appConfig, dialog, dummy) {
var NavigationCtrl = function($scope, $location, $q, account, email, outbox, notification, appConfig, dialog, dummy) {
if (!$location.search().dev && !account.isLoggedIn()) {
$location.path('/'); // init app
return;
@ -102,13 +102,19 @@ var NavigationCtrl = function($scope, $location, account, email, outbox, notific
});
ob.count = count;
email.refreshFolder({
folder: ob
}, dialog.error);
return $q(function(resolve) {
resolve();
}).then(function() {
return email.refreshFolder({
folder: ob
});
}).catch(dialog.error);
};
$scope.logout = function() {
dialog.confirm({
return dialog.confirm({
title: str.logoutTitle,
message: str.logoutMessage,
callback: function(confirm) {

View File

@ -2,7 +2,7 @@
var util = require('crypto-lib').util;
var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
var PrivateKeyUploadCtrl = function($scope, $q, keychain, pgp, dialog, auth) {
//
// scope state
@ -19,16 +19,15 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
// show syncing status
$scope.step = 4;
// check if key is already synced
$scope.checkServerForKey(function(privateKeySynced) {
return $scope.checkServerForKey().then(function(privateKeySynced) {
if (privateKeySynced) {
// close lightbox
$scope.state.lightbox = undefined;
// show message
dialog.info({
return dialog.info({
title: 'Info',
message: 'Your PGP key has already been synced.'
});
return;
}
// show sync ui if key is not synced
@ -41,24 +40,19 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
// scope functions
//
$scope.checkServerForKey = function(callback) {
$scope.checkServerForKey = function() {
var keyParams = pgp.getKeyParams();
keychain.hasPrivateKey({
userId: keyParams.userId,
keyId: keyParams._id
}, function(err, privateKeySynced) {
if (err) {
dialog.error(err);
return;
}
if (privateKeySynced) {
callback(privateKeySynced);
return;
}
return $q(function(resolve) {
resolve();
callback();
});
}).then(function() {
return keychain.hasPrivateKey({
userId: keyParams.userId,
keyId: keyParams._id
});
}).catch(dialog.error);
};
$scope.displayUploadUi = function() {
@ -82,29 +76,37 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
return true;
};
$scope.setDeviceName = function(callback) {
keychain.setDeviceName($scope.deviceName, callback);
$scope.setDeviceName = function() {
return $q(function(resolve) {
resolve();
}).then(function() {
return keychain.setDeviceName($scope.deviceName);
});
};
$scope.encryptAndUploadKey = function(callback) {
$scope.encryptAndUploadKey = function() {
var userId = auth.emailAddress;
var code = $scope.code;
// register device to keychain service
keychain.registerDevice({
userId: userId
}, function(err) {
if (err) {
dialog.error(err);
return;
}
return $q(function(resolve) {
resolve();
}).then(function() {
// register the device
return keychain.registerDevice({
userId: userId
});
}).then(function() {
// encrypt private PGP key using code and upload
keychain.uploadPrivateKey({
return keychain.uploadPrivateKey({
userId: userId,
code: code
}, callback);
});
});
}).catch(dialog.error);
};
$scope.goBack = function() {
@ -126,32 +128,22 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
if ($scope.step === 3) {
// set device name to local storage
$scope.setDeviceName(function(err) {
if (err) {
dialog.error(err);
return;
}
return $scope.setDeviceName().then(function() {
// show spinner
$scope.step++;
$scope.$apply();
// init key sync
$scope.encryptAndUploadKey(function(err) {
if (err) {
dialog.error(err);
return;
}
return $scope.encryptAndUploadKey();
// close sync dialog
$scope.state.privateKeyUpload.toggle(false);
// show success message
dialog.info({
title: 'Success',
message: 'Whiteout Keychain setup successful!'
});
}).then(function() {
// close sync dialog
$scope.state.privateKeyUpload.toggle(false);
// show success message
dialog.info({
title: 'Success',
message: 'Whiteout Keychain setup successful!'
});
});
}).catch(dialog.error);
}
};

View File

@ -4,7 +4,7 @@
// Controller
//
var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keychain, appConfig, download, auth, dialog) {
var ReadCtrl = function($scope, $location, $q, email, invitation, outbox, pgp, keychain, appConfig, download, auth, dialog) {
var str = appConfig.string;
@ -52,25 +52,24 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
return;
}
$scope.keyId = 'Searching...';
keychain.getReceiverPublicKey(address, function(err, pubkey) {
if (err) {
dialog.error(err);
return;
}
return $q(function(resolve) {
$scope.keyId = 'Searching...';
resolve();
}).then(function() {
return keychain.getReceiverPublicKey(address);
}).then(function(pubkey) {
if (!pubkey) {
$scope.keyId = 'User has no key. Click to invite.';
$scope.$apply();
return;
}
var fpr = pgp.getFingerprint(pubkey.publicKey);
var formatted = fpr.slice(32);
$scope.keyId = 'PGP key: ' + formatted;
$scope.$apply();
});
}).catch(dialog.error);
};
$scope.$watch('state.mailList.selected', function(mail) {
@ -89,24 +88,20 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
function checkPublicKey(user) {
user.secure = undefined;
if (!keychain) {
return;
}
return $q(function(resolve) {
resolve();
keychain.getReceiverPublicKey(user.address, function(err, pubkey) {
if (err) {
dialog.error(err);
return;
}
}).then(function() {
return keychain.getReceiverPublicKey(user.address);
if (pubkey && pubkey.publicKey) {
}).then(function(pubkey) {
if (pubkey.publicKey) {
user.secure = true;
} else {
user.secure = false;
}
$scope.$apply();
});
}).catch(dialog.error);
}
$scope.download = function(attachment) {
@ -122,11 +117,18 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
var folder = $scope.state.nav.currentFolder;
var message = $scope.state.mailList.selected;
email.getAttachment({
folder: folder,
uid: message.uid,
attachment: attachment
}, dialog.error);
return $q(function(resolve) {
resolve();
}).then(function() {
return email.getAttachment({
folder: folder,
uid: message.uid,
attachment: attachment
});
}).catch(dialog.error);
};
$scope.invite = function(user) {
@ -135,20 +137,20 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
return;
}
$scope.keyId = 'Sending invitation...';
var sender = auth.emailAddress,
recipient = user.address;
invitation.invite({
recipient: recipient,
sender: sender
}, function(err) {
if (err) {
dialog.error(err);
return;
}
return $q(function(resolve) {
$scope.keyId = 'Sending invitation...';
resolve();
}).then(function() {
return invitation.invite({
recipient: recipient,
sender: sender
});
}).then(function() {
var invitationMail = {
from: [{
address: sender
@ -161,10 +163,10 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
subject: str.invitationSubject,
body: str.invitationMessage
};
// send invitation mail
outbox.put(invitationMail, dialog.error);
});
return outbox.put(invitationMail);
}).catch(dialog.error);
};
};

View File

@ -1,6 +1,6 @@
'use strict';
var SetPassphraseCtrl = function($scope, pgp, keychain, dialog) {
var SetPassphraseCtrl = function($scope, $q, pgp, keychain, dialog) {
//
// scope variables
@ -76,52 +76,44 @@ var SetPassphraseCtrl = function($scope, pgp, keychain, dialog) {
$scope.setPassphrase = function() {
var keyId = pgp.getKeyParams()._id;
keychain.lookupPrivateKey(keyId, function(err, savedKey) {
if (err) {
dialog.error(err);
return;
}
pgp.changePassphrase({
return $q(function(resolve) {
resolve();
}).then(function() {
return keychain.lookupPrivateKey(keyId);
}).then(function(savedKey) {
// change passphrase
return pgp.changePassphrase({
privateKeyArmored: savedKey.encryptedKey,
oldPassphrase: $scope.oldPassphrase,
newPassphrase: $scope.newPassphrase
}, onPassphraseChanged);
});
}).catch(function(err) {
err.showBugReporter = false;
throw err;
});
}).then(function(newPrivateKeyArmored) {
// persist new armored key
var keyParams = pgp.getKeyParams(newPrivateKeyArmored);
var privateKey = {
_id: keyParams._id,
userId: keyParams.userId,
userIds: keyParams.userIds,
encryptedKey: newPrivateKeyArmored
};
return keychain.saveLocalPrivateKey(privateKey);
}).then(function() {
$scope.state.setPassphrase.toggle(false);
return dialog.info({
title: 'Success',
message: 'Passphrase change complete.'
});
}).catch(dialog.error);
};
function onPassphraseChanged(err, newPrivateKeyArmored) {
if (err) {
err.showBugReporter = false;
dialog.error(err);
return;
}
// persist new armored key
var keyParams = pgp.getKeyParams(newPrivateKeyArmored);
var privateKey = {
_id: keyParams._id,
userId: keyParams.userId,
userIds: keyParams.userIds,
encryptedKey: newPrivateKeyArmored
};
keychain.saveLocalPrivateKey(privateKey, onKeyPersisted);
}
function onKeyPersisted(err) {
if (err) {
dialog.error(err);
return;
}
$scope.state.setPassphrase.toggle(false);
$scope.$apply();
dialog.info({
title: 'Success',
message: 'Passphrase change complete.'
});
}
};
module.exports = SetPassphraseCtrl;

View File

@ -218,34 +218,31 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
return;
}
// keychain is undefined in local dev environment
if (keychain) {
// 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
keychain.refreshKeyForUserId({
// 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({
userId: recipient.address
}, function(err, key) {
if (err) {
dialog.error(err);
return;
}
if (key) {
// compare again since model could have changed during the roundtrip
var matchingUserId = _.findWhere(key.userIds, {
emailAddress: recipient.address
});
// compare either primary userId or (if available) multiple IDs
if (key.userId === recipient.address || matchingUserId) {
recipient.key = key;
recipient.secure = true;
}
}
$scope.checkSendStatus();
$scope.$digest();
});
}
}).then(function(key) {
if (key) {
// compare again since model could have changed during the roundtrip
var matchingUserId = _.findWhere(key.userIds, {
emailAddress: recipient.address
});
// compare either primary userId or (if available) multiple IDs
if (key.userId === recipient.address || matchingUserId) {
recipient.key = key;
recipient.secure = true;
}
}
$scope.checkSendStatus();
}).catch(dialog.error);
};
/**
@ -347,12 +344,13 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
}
// persist the email to disk for later sending
outbox.put(message, function(err) {
if (err) {
dialog.error(err);
return;
}
return $q(function(resolve) {
resolve();
}).then(function() {
return outbox.put(message);
}).then(function() {
// if we need to synchronize replyTo.answered = true to imap,
// let's do that. otherwise, we're done
if (!$scope.replyTo || $scope.replyTo.answered) {
@ -360,20 +358,16 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
}
$scope.replyTo.answered = true;
email.setFlags({
return email.setFlags({
folder: currentFolder(),
message: $scope.replyTo
}, function(err) {
if (err && err.code !== 42) {
dialog.error(err);
return;
}
// offline or no error, let's apply the ui changes
$scope.$apply();
});
});
}).catch(function(err) {
if (err.code !== 42) {
dialog.error(err);
}
});
};
//
@ -389,37 +383,29 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
};
$scope.lookupAddressBook = function(query) {
var deferred = $q.defer();
return $q(function(resolve) {
resolve();
if (!$scope.addressBookCache) {
}).then(function() {
if ($scope.addressBookCache) {
return;
}
// populate address book cache
keychain.listLocalPublicKeys(function(err, keys) {
if (err) {
dialog.error(err);
return;
}
return keychain.listLocalPublicKeys().then(function(keys) {
$scope.addressBookCache = keys.map(function(key) {
return {
address: key.userId
};
});
filter();
});
} else {
filter();
}
// query address book cache
function filter() {
var addresses = $scope.addressBookCache.filter(function(i) {
}).then(function() {
// filter the address book cache
return $scope.addressBookCache.filter(function(i) {
return i.address.indexOf(query) !== -1;
});
deferred.resolve(addresses);
}
return deferred.promise;
}).catch(dialog.error);
};
//