mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-07 09:25:09 +00:00
(js) Improve message viewer/editor in popup window
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
const:jsFiles="Common.js, Preferences.services.js, Contacts.services.js, Mailer.app.popup.js, Mailer.services.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/angular-file-upload.min.js">
|
||||
|
||||
<main class="layout-fill" ng-controller="navController">
|
||||
<div id="detailView" class="view-detail"
|
||||
<div id="detailView" class="view-detail md-default-theme md-background md-bg md-hue-1"
|
||||
layout="column" layout-align="start center"
|
||||
ui-view="message">
|
||||
<div class="sg-progress-circular-floating">
|
||||
|
||||
@@ -23,12 +23,11 @@
|
||||
ng-click="viewer.close()">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex hide show-xs"><!-- spacer --></div>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button" label:aria-label="flagged" ng-click="viewer.message.toggleFlag()">
|
||||
<md-icon ng-class="{'icon-star': viewer.message.isflagged,
|
||||
'icon-star-border': !viewer.message.isflagged}"><!-- flag --></md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex hide-xs"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button"
|
||||
ng-hide="viewer.message.isDraft"
|
||||
ng-click="viewer.reply($event)"
|
||||
@@ -153,6 +152,7 @@
|
||||
md-selected-item-change="viewer.message.addTag(viewer.tags.selected.name)"
|
||||
md-search-text="viewer.tags.searchText"
|
||||
md-items="tag in viewer.service.filterTags(viewer.tags.searchText)"
|
||||
md-item-text="tag.description"
|
||||
md-autoselect="true"
|
||||
label:placeholder="Add a tag">
|
||||
<md-item-template>
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
MailboxController.$inject = ['$state', '$timeout', '$mdDialog', 'stateAccounts', 'stateAccount', 'stateMailbox', 'encodeUriFilter', 'Dialog', 'Account', 'Mailbox'];
|
||||
function MailboxController($state, $timeout, $mdDialog, stateAccounts, stateAccount, stateMailbox, encodeUriFilter, Dialog, Account, Mailbox) {
|
||||
MailboxController.$inject = ['$window', '$state', '$timeout', '$mdDialog', 'stateAccounts', 'stateAccount', 'stateMailbox', 'encodeUriFilter', 'Dialog', 'Account', 'Mailbox'];
|
||||
function MailboxController($window, $state, $timeout, $mdDialog, stateAccounts, stateAccount, stateMailbox, encodeUriFilter, Dialog, Account, Mailbox) {
|
||||
var vm = this, messageDialog = null;
|
||||
|
||||
// Expose controller
|
||||
$window.$mailboxController = vm;
|
||||
|
||||
Mailbox.selectedFolder = stateMailbox;
|
||||
|
||||
vm.service = Mailbox;
|
||||
|
||||
@@ -101,10 +101,18 @@
|
||||
*/
|
||||
stateAccounts.$inject = ['$q', 'Account'];
|
||||
function stateAccounts($q, Account) {
|
||||
var promise = Account.$findAll();
|
||||
// Fetch list of mailboxes for each account
|
||||
return promise.then(function(accounts) {
|
||||
var promises = [];
|
||||
var accounts, promises = [];
|
||||
|
||||
if (window &&
|
||||
window.opener &&
|
||||
window.opener.$mailboxController) {
|
||||
// Mail accounts are available from the parent window
|
||||
accounts = window.opener.$mailboxController.accounts;
|
||||
return $q.when(accounts);
|
||||
}
|
||||
else {
|
||||
accounts = Account.$findAll();
|
||||
// Fetch list of mailboxes for each account
|
||||
angular.forEach(accounts, function(account, i) {
|
||||
var mailboxes = account.$getMailboxes();
|
||||
promises.push(mailboxes.then(function(objects) {
|
||||
@@ -112,7 +120,7 @@
|
||||
}));
|
||||
});
|
||||
return $q.all(promises);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,12 +168,26 @@
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
stateMessage.$inject = ['encodeUriFilter', '$stateParams', '$state', 'stateMailbox', 'Message'];
|
||||
function stateMessage(encodeUriFilter, $stateParams, $state, stateMailbox, Message) {
|
||||
var data = { uid: $stateParams.messageId.toString() },
|
||||
message = new Message(stateMailbox.$account.id, stateMailbox, data);
|
||||
stateMessage.$inject = ['encodeUriFilter', '$q', '$stateParams', '$state', 'stateMailbox', 'Message'];
|
||||
function stateMessage(encodeUriFilter, $q, $stateParams, $state, stateMailbox, Message) {
|
||||
var data, message;
|
||||
|
||||
return message.$reload();
|
||||
if (window &&
|
||||
window.opener &&
|
||||
window.opener.$messageController &&
|
||||
window.opener.$messageController.message.uid == parseInt($stateParams.messageId)) {
|
||||
// Message is available from the parent window
|
||||
message = new Message(stateMailbox.$account.id,
|
||||
stateMailbox,
|
||||
window.opener.$messageController.message.$omit());
|
||||
return $q.when(message);
|
||||
}
|
||||
else {
|
||||
// Message is not available; load it from the server
|
||||
data = { uid: $stateParams.messageId.toString() };
|
||||
message = new Message(stateMailbox.$account.id, stateMailbox, data);
|
||||
return message.$reload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,10 +201,14 @@
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
runBlock.$inject = ['$rootScope'];
|
||||
function runBlock($rootScope) {
|
||||
runBlock.$inject = ['$window', '$rootScope', '$log'];
|
||||
function runBlock($window, $rootScope, $log) {
|
||||
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
|
||||
$log.error(error);
|
||||
$window.close();
|
||||
});
|
||||
$rootScope.$on('$routeChangeError', function(event, current, previous, rejection) {
|
||||
console.error(event, current, previous, rejection);
|
||||
$log.error(event, current, previous, rejection);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -207,8 +233,7 @@
|
||||
}
|
||||
})
|
||||
.finally(function() {
|
||||
if ($window.opener)
|
||||
$window.close();
|
||||
$window.close();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,11 @@
|
||||
// Data is immediately available
|
||||
if (typeof futureMessageData.then !== 'function') {
|
||||
//console.debug(JSON.stringify(futureMessageData, undefined, 2));
|
||||
if (angular.isDefined(lazy) && lazy) {
|
||||
this.uid = futureMessageData.uid;
|
||||
}
|
||||
else {
|
||||
if (angular.isUndefined(lazy) || !lazy) {
|
||||
angular.extend(this, futureMessageData);
|
||||
this.$formatFullAddresses();
|
||||
}
|
||||
this.uid = parseInt(futureMessageData.uid);
|
||||
}
|
||||
else {
|
||||
// The promise will be unwrapped first
|
||||
@@ -132,7 +130,7 @@
|
||||
var oldUID = (this.uid || -1);
|
||||
|
||||
if (oldUID != parseInt(uid)) {
|
||||
this.uid = uid;
|
||||
this.uid = parseInt(uid);
|
||||
if (oldUID > -1) {
|
||||
oldUID = oldUID.toString();
|
||||
if (angular.isDefined(this.$mailbox.uidsMap[oldUID])) {
|
||||
@@ -142,7 +140,8 @@
|
||||
}
|
||||
else {
|
||||
// Refresh selected folder if it's the drafts mailbox
|
||||
if (this.$mailbox.constructor.selectedFolder.type == 'draft') {
|
||||
if (this.$mailbox.constructor.selectedFolder &&
|
||||
this.$mailbox.constructor.selectedFolder.type == 'draft') {
|
||||
this.$mailbox.constructor.selectedFolder.$filter();
|
||||
}
|
||||
}
|
||||
@@ -646,13 +645,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Format addresses as arrays
|
||||
_.each(['from', 'to', 'cc', 'bcc', 'reply-to'], function(type) {
|
||||
if (message[type])
|
||||
message[type] = _.invoke(message[type].split(','), 'trim');
|
||||
});
|
||||
|
||||
//Message.$log.debug(JSON.stringify(message, undefined, 2));
|
||||
return message;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
function MessageController($window, $scope, $state, $mdDialog, stateAccounts, stateAccount, stateMailbox, stateMessage, encodeUriFilter, sgSettings, focus, Dialog, Account, Mailbox, Message) {
|
||||
var vm = this, messageDialog = null, popupWindow = null;
|
||||
|
||||
// Expose controller
|
||||
$window.$messageController = vm;
|
||||
|
||||
vm.$state = $state;
|
||||
vm.accounts = stateAccounts;
|
||||
vm.account = stateAccount;
|
||||
vm.mailbox = stateMailbox;
|
||||
@@ -32,14 +36,54 @@
|
||||
vm.toggleRawSource = toggleRawSource;
|
||||
vm.showRawSource = false;
|
||||
|
||||
// Watch the message model "flags" attribute to remove on-the-fly a tag from the IMAP message
|
||||
// when removed from the message viewer.
|
||||
// TODO: this approach should be reviewed once md-chips supports ng-change.
|
||||
$scope.$watchCollection('viewer.message.flags', function(oldTags, newTags) {
|
||||
_.each(_.difference(newTags, oldTags), function(tag) {
|
||||
vm.message.removeTag(tag);
|
||||
// One-way refresh of the parent window when modifying the message from a popup window.
|
||||
if ($window.opener) {
|
||||
// Update the message flags. The message must be displayed in the parent window.
|
||||
$scope.$watchCollection('viewer.message.flags', function(newTags, oldTags) {
|
||||
var ctrls;
|
||||
if (newTags || oldTags) {
|
||||
ctrls = $parentControllers();
|
||||
if (ctrls.messageCtrl) {
|
||||
ctrls.messageCtrl.service.$timeout(function() {
|
||||
ctrls.messageCtrl.message.flags = newTags;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// Update the "isflagged" (star icon) of the message. The mailbox must be displayed in the parent window.
|
||||
$scope.$watch('viewer.message.isflagged', function(isflagged, wasflagged) {
|
||||
var ctrls = $parentControllers();
|
||||
if (ctrls.mailboxCtrl) {
|
||||
ctrls.mailboxCtrl.service.$timeout(function() {
|
||||
var message = _.find(ctrls.mailboxCtrl.selectedFolder.$messages, { uid: vm.message.uid });
|
||||
message.isflagged = isflagged;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is a popup window, retrieve the matching controllers (mailbox and message) of the parent window.
|
||||
*/
|
||||
function $parentControllers() {
|
||||
var message, mailbox, ctrls = {};
|
||||
if ($window.opener) {
|
||||
// Deleting the message from a popup window
|
||||
if ($window.opener.$mailboxController &&
|
||||
$window.opener.$mailboxController.selectedFolder.$id() == stateMailbox.$id()) {
|
||||
// The message mailbox is opened in the parent window
|
||||
mailbox = $window.opener.$mailboxController;
|
||||
ctrls.mailboxCtrl = mailbox;
|
||||
if ($window.opener.$messageController &&
|
||||
$window.opener.$messageController.message.uid == stateMessage.uid) {
|
||||
// The message is opened in the parent window
|
||||
message = $window.opener.$messageController;
|
||||
ctrls.messageCtrl = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctrls;
|
||||
}
|
||||
|
||||
function showDetailedRecipients($event) {
|
||||
vm.$showDetailedRecipients = true;
|
||||
@@ -48,16 +92,36 @@
|
||||
}
|
||||
|
||||
function doDelete() {
|
||||
stateMailbox.$deleteMessages([stateMessage]).then(function() {
|
||||
var parentCtrls = $parentControllers(), mailbox, message, state;
|
||||
|
||||
if (parentCtrls.messageCtrl) {
|
||||
mailbox = parentCtrls.mailboxCtrl.selectedFolder;
|
||||
message = parentCtrls.messageCtrl.message;
|
||||
state = parentCtrls.messageCtrl.$state;
|
||||
}
|
||||
else {
|
||||
mailbox = stateMailbox;
|
||||
message = stateMessage;
|
||||
state = $state;
|
||||
}
|
||||
|
||||
mailbox.$deleteMessages([message]).then(function() {
|
||||
// Remove message from list of messages
|
||||
var index = _.findIndex(stateMailbox.$messages, function(o) {
|
||||
return o.uid == stateMessage.uid;
|
||||
var index = _.findIndex(mailbox.$messages, function(o) {
|
||||
return o.uid == message.uid;
|
||||
});
|
||||
if (index != -1)
|
||||
stateMailbox.$messages.splice(index, 1);
|
||||
mailbox.$messages.splice(index, 1);
|
||||
// Remove message object from scope
|
||||
vm.message = null;
|
||||
$state.go('mail.account.mailbox', { accountId: stateAccount.id, mailboxId: encodeUriFilter(stateMailbox.path) });
|
||||
message = null;
|
||||
// Navigate to mailbox if not in popup window
|
||||
if (angular.isDefined(state)) {
|
||||
try {
|
||||
state.go('mail.account.mailbox', { mailboxId: encodeUriFilter(mailbox.path) });
|
||||
}
|
||||
catch (error) {}
|
||||
}
|
||||
closePopup();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,18 +141,20 @@
|
||||
controllerAs: 'editor',
|
||||
locals: {
|
||||
stateAccounts: vm.accounts,
|
||||
stateAccount: vm.account,
|
||||
stateMessage: message,
|
||||
stateRecipients: recipients
|
||||
}
|
||||
})
|
||||
.finally(function() {
|
||||
messageDialog = null;
|
||||
closePopup();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
$state.go('mail.account.mailbox', { accountId: stateAccount.id, mailboxId: encodeUriFilter(stateMailbox.path) }).then(function() {
|
||||
$state.go('mail.account.mailbox').then(function() {
|
||||
vm.message = null;
|
||||
delete stateMailbox.selectedMessage;
|
||||
});
|
||||
@@ -139,7 +205,8 @@
|
||||
}
|
||||
|
||||
function closePopup() {
|
||||
$window.close();
|
||||
if ($window.opener)
|
||||
$window.close();
|
||||
}
|
||||
|
||||
function newMessage($event, recipient) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
MessageEditorController.$inject = ['$stateParams', '$mdConstant', '$mdDialog', '$mdToast', 'FileUploader', 'stateAccounts', 'stateMessage', 'stateRecipients', '$timeout', 'Dialog', 'AddressBook', 'Card', 'Preferences'];
|
||||
function MessageEditorController($stateParams, $mdConstant, $mdDialog, $mdToast, FileUploader, stateAccounts, stateMessage, stateRecipients, $timeout, Dialog, AddressBook, Card, Preferences) {
|
||||
MessageEditorController.$inject = ['$window', '$stateParams', '$mdConstant', '$mdDialog', '$mdToast', 'FileUploader', 'stateAccounts', 'stateAccount', 'stateMessage', 'stateRecipients', 'encodeUriFilter', '$timeout', 'Dialog', 'AddressBook', 'Card', 'Preferences'];
|
||||
function MessageEditorController($window, $stateParams, $mdConstant, $mdDialog, $mdToast, FileUploader, stateAccounts, stateAccount, stateMessage, stateRecipients, encodeUriFilter, $timeout, Dialog, AddressBook, Card, Preferences) {
|
||||
var vm = this, semicolon = 186;
|
||||
|
||||
vm.addRecipient = addRecipient;
|
||||
@@ -77,6 +77,33 @@
|
||||
vm.message.editable.to = _.union(vm.message.editable.to, _.pluck(stateRecipients, 'full'));
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is a popup window, retrieve the mailbox controller of the parent window.
|
||||
*/
|
||||
function $parentControllers() {
|
||||
var originMessage, ctrls = {};
|
||||
if ($window.opener) {
|
||||
if ($window.opener.$mailboxController) {
|
||||
if ($window.opener.$mailboxController.selectedFolder.type == 'draft') {
|
||||
ctrls.draftMailboxCtrl = $window.opener.$mailboxController;
|
||||
if ($window.opener.$messageController &&
|
||||
$window.opener.$messageController.message.uid == stateMessage.uid) {
|
||||
// The draft is opened in the parent window
|
||||
ctrls.draftMessageCtrl = $window.opener.$messageController;
|
||||
}
|
||||
}
|
||||
else if (stateMessage.origin) {
|
||||
originMessage = stateMessage.origin.message;
|
||||
if ($window.opener.$mailboxController.selectedFolder.$id() == originMessage.$mailbox.$id()) {
|
||||
// The message mailbox is opened in the parent window
|
||||
ctrls.originMailboxCtrl = $window.opener.$mailboxController;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctrls;
|
||||
}
|
||||
|
||||
function addAttachments() {
|
||||
// Add existing attached files to uploader
|
||||
var i, data, fileItem;
|
||||
@@ -114,7 +141,18 @@
|
||||
}
|
||||
|
||||
function save() {
|
||||
var ctrls = $parentControllers();
|
||||
vm.message.$save().then(function(data) {
|
||||
if (ctrls.draftMailboxCtrl) {
|
||||
// We're saving a draft from a popup window.
|
||||
// Reload draft mailbox
|
||||
ctrls.draftMailboxCtrl.selectedFolder.$filter().then(function() {
|
||||
if (ctrls.draftMessageCtrl) {
|
||||
// Reload selected message
|
||||
ctrls.draftMessageCtrl.$state.go('mail.account.mailbox.message', { messageId: vm.message.uid });
|
||||
}
|
||||
});
|
||||
}
|
||||
$mdToast.show(
|
||||
$mdToast.simple()
|
||||
.content(l('Your email has been saved'))
|
||||
@@ -124,10 +162,26 @@
|
||||
}
|
||||
|
||||
function send() {
|
||||
var ctrls = $parentControllers();
|
||||
if (vm.autosave)
|
||||
$timeout.cancel(vm.autosave);
|
||||
|
||||
vm.message.$send().then(function(data) {
|
||||
if (ctrls.draftMailboxCtrl) {
|
||||
// We're sending a draft from a popup window and the draft mailbox is opened.
|
||||
// Reload draft mailbox
|
||||
ctrls.draftMailboxCtrl.selectedFolder.$filter().then(function() {
|
||||
if (ctrls.draftMessageCtrl) {
|
||||
// Close draft
|
||||
ctrls.draftMessageCtrl.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (ctrls.originMailboxCtrl) {
|
||||
// We're sending a draft from a popup window and the original mailbox is opened.
|
||||
// Reload mailbox
|
||||
ctrls.originMailboxCtrl.selectedFolder.$filter();
|
||||
}
|
||||
$mdToast.show(
|
||||
$mdToast.simple()
|
||||
.content(l('Your email has been sent'))
|
||||
|
||||
Reference in New Issue
Block a user