2015-05-06 04:06:13 +02:00
|
|
|
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ngInject
|
|
|
|
*/
|
2016-05-18 20:35:24 +02:00
|
|
|
MessageController.$inject = ['$window', '$scope', '$state', '$mdMedia', '$mdDialog', 'sgConstant', 'stateAccounts', 'stateAccount', 'stateMailbox', 'stateMessage', 'encodeUriFilter', 'sgSettings', 'sgFocus', 'Dialog', 'Calendar', 'Component', 'Account', 'Mailbox', 'Message'];
|
|
|
|
function MessageController($window, $scope, $state, $mdMedia, $mdDialog, sgConstant, stateAccounts, stateAccount, stateMailbox, stateMessage, encodeUriFilter, sgSettings, focus, Dialog, Calendar, Component, Account, Mailbox, Message) {
|
2015-09-04 23:31:16 +02:00
|
|
|
var vm = this, messageDialog = null, popupWindow = null;
|
2015-07-13 21:22:58 +02:00
|
|
|
|
2016-01-07 21:43:26 +01:00
|
|
|
// Expose controller
|
|
|
|
$window.$messageController = vm;
|
|
|
|
|
|
|
|
vm.$state = $state;
|
2015-08-02 19:25:38 +02:00
|
|
|
vm.accounts = stateAccounts;
|
2015-07-13 21:22:58 +02:00
|
|
|
vm.account = stateAccount;
|
|
|
|
vm.mailbox = stateMailbox;
|
|
|
|
vm.message = stateMessage;
|
|
|
|
vm.service = Message;
|
|
|
|
vm.tags = { searchText: '', selected: '' };
|
2015-12-04 21:00:58 +01:00
|
|
|
vm.showFlags = stateMessage.flags && stateMessage.flags.length > 0;
|
2015-12-07 20:07:48 +01:00
|
|
|
vm.$showDetailedRecipients = false;
|
2016-02-26 21:19:33 +01:00
|
|
|
vm.toggleDetailedRecipients = toggleDetailedRecipients;
|
2016-05-11 03:29:18 +02:00
|
|
|
vm.filterMailtoLinks = filterMailtoLinks;
|
2016-05-17 22:39:12 +02:00
|
|
|
vm.deleteMessage = deleteMessage;
|
2015-08-26 23:28:03 +02:00
|
|
|
vm.close = close;
|
2015-08-02 19:25:38 +02:00
|
|
|
vm.reply = reply;
|
|
|
|
vm.replyAll = replyAll;
|
|
|
|
vm.forward = forward;
|
|
|
|
vm.edit = edit;
|
2015-09-04 23:31:16 +02:00
|
|
|
vm.openPopup = openPopup;
|
|
|
|
vm.closePopup = closePopup;
|
2015-08-09 16:36:54 +02:00
|
|
|
vm.newMessage = newMessage;
|
2015-12-04 21:00:58 +01:00
|
|
|
vm.toggleRawSource = toggleRawSource;
|
|
|
|
vm.showRawSource = false;
|
2016-02-26 21:41:53 +01:00
|
|
|
vm.print = print;
|
2016-02-10 22:15:00 +01:00
|
|
|
vm.convertToEvent = convertToEvent;
|
|
|
|
vm.convertToTask = convertToTask;
|
2015-07-13 21:22:58 +02:00
|
|
|
|
2016-01-07 21:43:26 +01:00
|
|
|
// 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;
|
|
|
|
});
|
|
|
|
}
|
2015-07-13 21:22:58 +02:00
|
|
|
});
|
2016-01-07 21:43:26 +01:00
|
|
|
}
|
2016-03-28 16:42:40 +02:00
|
|
|
else {
|
|
|
|
// Flatten new tags when coming from the predefined list of tags (Message.$tags) and
|
|
|
|
// sync tags with server when adding or removing a tag.
|
2016-05-11 03:18:51 +02:00
|
|
|
$scope.$watchCollection('viewer.message.flags', function(_newTags, _oldTags) {
|
|
|
|
var newTags, oldTags, tags;
|
|
|
|
if (_newTags || _oldTags) {
|
|
|
|
newTags = _newTags || [];
|
|
|
|
oldTags = _oldTags || [];
|
2016-03-28 16:42:40 +02:00
|
|
|
_.forEach(newTags, function(tag, i) {
|
|
|
|
if (angular.isObject(tag))
|
|
|
|
newTags[i] = tag.name;
|
|
|
|
});
|
|
|
|
if (newTags.length > oldTags.length) {
|
|
|
|
tags = _.difference(newTags, oldTags);
|
|
|
|
_.forEach(tags, function(tag) {
|
|
|
|
vm.message.addTag(tag);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else if (newTags.length < oldTags.length) {
|
|
|
|
tags = _.difference(oldTags, newTags);
|
|
|
|
_.forEach(tags, function(tag) {
|
|
|
|
vm.message.removeTag(tag);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-01-07 21:43:26 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
2015-07-13 21:22:58 +02:00
|
|
|
|
2016-02-26 21:19:33 +01:00
|
|
|
function toggleDetailedRecipients($event) {
|
|
|
|
vm.$showDetailedRecipients = !vm.$showDetailedRecipients;
|
2015-12-07 20:07:48 +01:00
|
|
|
$event.stopPropagation();
|
|
|
|
$event.preventDefault();
|
|
|
|
}
|
|
|
|
|
2016-05-11 03:29:18 +02:00
|
|
|
function filterMailtoLinks($event) {
|
|
|
|
var href, match, to, cc, bcc, subject, body, data;
|
|
|
|
if ($event.target.tagName == 'A' && 'href' in $event.target.attributes) {
|
|
|
|
href = $event.target.attributes.href.value;
|
|
|
|
match = /^mailto:([^\?]+)/.exec(href);
|
|
|
|
if (match) {
|
|
|
|
// Recipients
|
|
|
|
to = _.map(decodeURIComponent(match[1]).split(','), function(email) {
|
|
|
|
return '<' + email + '>';
|
|
|
|
});
|
|
|
|
data = { to: to };
|
|
|
|
// Subject & body
|
|
|
|
_.forEach(['subject', 'body'], function(param) {
|
|
|
|
var re = new RegExp(param + '=([^&]+)');
|
|
|
|
param = (param == 'body')? 'text' : param;
|
|
|
|
match = re.exec(href);
|
|
|
|
if (match)
|
|
|
|
data[param] = [decodeURIComponent(match[1])];
|
|
|
|
});
|
|
|
|
// Recipients
|
|
|
|
_.forEach(['cc', 'bcc'], function(param) {
|
|
|
|
var re = new RegExp(param + '=([^&]+)');
|
|
|
|
match = re.exec(href);
|
|
|
|
if (match)
|
|
|
|
data[param] = [decodeURIComponent(match[1])];
|
|
|
|
});
|
|
|
|
newMessage($event, data); // will stop event propagation
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-17 22:39:12 +02:00
|
|
|
function deleteMessage() {
|
2016-01-08 22:31:06 +01:00
|
|
|
var mailbox, message, state, nextMessage, previousMessage,
|
|
|
|
parentCtrls = $parentControllers();
|
2016-01-07 21:43:26 +01:00
|
|
|
|
|
|
|
if (parentCtrls.messageCtrl) {
|
|
|
|
mailbox = parentCtrls.mailboxCtrl.selectedFolder;
|
|
|
|
message = parentCtrls.messageCtrl.message;
|
|
|
|
state = parentCtrls.messageCtrl.$state;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mailbox = stateMailbox;
|
|
|
|
message = stateMessage;
|
|
|
|
state = $state;
|
|
|
|
}
|
|
|
|
|
2016-01-08 22:31:06 +01:00
|
|
|
mailbox.$deleteMessages([message]).then(function(index) {
|
|
|
|
var nextIndex = index;
|
2015-05-08 21:47:09 +02:00
|
|
|
// Remove message object from scope
|
2016-01-07 21:43:26 +01:00
|
|
|
message = null;
|
|
|
|
if (angular.isDefined(state)) {
|
2016-01-08 22:31:06 +01:00
|
|
|
// Select either the next or previous message
|
|
|
|
if (index > 0) {
|
|
|
|
nextIndex -= 1;
|
|
|
|
nextMessage = mailbox.$messages[nextIndex];
|
|
|
|
}
|
|
|
|
if (index < mailbox.$messages.length)
|
|
|
|
previousMessage = mailbox.$messages[index];
|
|
|
|
|
|
|
|
if (nextMessage) {
|
|
|
|
if (nextMessage.isread && previousMessage && !previousMessage.isread) {
|
|
|
|
nextIndex = index;
|
|
|
|
nextMessage = previousMessage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (previousMessage) {
|
|
|
|
nextIndex = index;
|
|
|
|
nextMessage = previousMessage;
|
|
|
|
}
|
|
|
|
|
2016-01-07 21:43:26 +01:00
|
|
|
try {
|
2016-05-18 20:35:24 +02:00
|
|
|
if (nextMessage && $mdMedia(sgConstant['gt-md'])) {
|
2016-01-08 22:31:06 +01:00
|
|
|
state.go('mail.account.mailbox.message', { messageId: nextMessage.uid });
|
2016-02-03 16:51:59 +01:00
|
|
|
if (nextIndex < mailbox.$topIndex)
|
|
|
|
mailbox.$topIndex = nextIndex;
|
|
|
|
else if (nextIndex > mailbox.$lastVisibleIndex)
|
|
|
|
mailbox.$topIndex = nextIndex - (mailbox.$lastVisibleIndex - mailbox.$topIndex);
|
2016-01-08 22:31:06 +01:00
|
|
|
}
|
|
|
|
else {
|
2016-05-17 22:39:12 +02:00
|
|
|
state.go('mail.account.mailbox').then(function() {
|
|
|
|
message = null;
|
|
|
|
delete mailbox.selectedMessage;
|
|
|
|
});
|
2016-01-08 22:31:06 +01:00
|
|
|
}
|
2016-01-07 21:43:26 +01:00
|
|
|
}
|
|
|
|
catch (error) {}
|
|
|
|
}
|
|
|
|
closePopup();
|
2015-05-06 04:06:13 +02:00
|
|
|
});
|
2015-07-13 21:22:58 +02:00
|
|
|
}
|
2015-08-02 19:25:38 +02:00
|
|
|
|
2016-05-11 03:29:18 +02:00
|
|
|
function showMailEditor($event, message) {
|
2015-08-27 03:22:39 +02:00
|
|
|
if (messageDialog === null) {
|
|
|
|
messageDialog = $mdDialog
|
|
|
|
.show({
|
|
|
|
parent: angular.element(document.body),
|
|
|
|
targetEvent: $event,
|
|
|
|
clickOutsideToClose: false,
|
|
|
|
escapeToClose: false,
|
|
|
|
templateUrl: 'UIxMailEditor',
|
|
|
|
controller: 'MessageEditorController',
|
|
|
|
controllerAs: 'editor',
|
|
|
|
locals: {
|
|
|
|
stateAccounts: vm.accounts,
|
2016-01-07 21:43:26 +01:00
|
|
|
stateAccount: vm.account,
|
2016-05-11 03:29:18 +02:00
|
|
|
stateMessage: message
|
2015-08-27 03:22:39 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.finally(function() {
|
|
|
|
messageDialog = null;
|
2016-01-07 21:43:26 +01:00
|
|
|
closePopup();
|
2015-08-27 03:22:39 +02:00
|
|
|
});
|
|
|
|
}
|
2015-08-02 19:25:38 +02:00
|
|
|
}
|
|
|
|
|
2015-08-26 23:28:03 +02:00
|
|
|
function close() {
|
2016-01-07 21:43:26 +01:00
|
|
|
$state.go('mail.account.mailbox').then(function() {
|
2015-08-26 23:28:03 +02:00
|
|
|
vm.message = null;
|
|
|
|
delete stateMailbox.selectedMessage;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-08-02 19:25:38 +02:00
|
|
|
function reply($event) {
|
|
|
|
var message = vm.message.$reply();
|
|
|
|
showMailEditor($event, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
function replyAll($event) {
|
|
|
|
var message = vm.message.$replyAll();
|
|
|
|
showMailEditor($event, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
function forward($event) {
|
|
|
|
var message = vm.message.$forward();
|
|
|
|
showMailEditor($event, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
function edit($event) {
|
2015-08-04 16:56:55 +02:00
|
|
|
vm.message.$editableContent().then(function() {
|
|
|
|
showMailEditor($event, vm.message);
|
|
|
|
});
|
2015-08-02 19:25:38 +02:00
|
|
|
}
|
2015-08-04 22:51:33 +02:00
|
|
|
|
2015-09-04 23:31:16 +02:00
|
|
|
function openPopup() {
|
|
|
|
var url = [sgSettings.baseURL(),
|
|
|
|
'UIxMailPopupView#/Mail',
|
|
|
|
vm.message.accountId,
|
|
|
|
// The double-encoding is necessary
|
|
|
|
encodeUriFilter(encodeUriFilter(vm.message.$mailbox.path)),
|
|
|
|
vm.message.uid]
|
|
|
|
.join('/'),
|
|
|
|
wId = vm.message.$absolutePath();
|
|
|
|
popupWindow = $window.open(url, wId,
|
|
|
|
["width=680",
|
|
|
|
"height=520",
|
|
|
|
"resizable=1",
|
|
|
|
"scrollbars=1",
|
|
|
|
"toolbar=0",
|
|
|
|
"location=0",
|
|
|
|
"directories=0",
|
|
|
|
"status=0",
|
|
|
|
"menubar=0",
|
|
|
|
"copyhistory=0"]
|
|
|
|
.join(','));
|
|
|
|
}
|
|
|
|
|
|
|
|
function closePopup() {
|
2016-01-07 21:43:26 +01:00
|
|
|
if ($window.opener)
|
|
|
|
$window.close();
|
2015-09-04 23:31:16 +02:00
|
|
|
}
|
|
|
|
|
2016-05-11 03:29:18 +02:00
|
|
|
function newMessage($event, editableContent) {
|
|
|
|
vm.account.$newMessage().then(function(message) {
|
|
|
|
angular.extend(message.editable, editableContent);
|
|
|
|
showMailEditor($event, message);
|
|
|
|
});
|
2015-12-07 20:07:48 +01:00
|
|
|
$event.stopPropagation();
|
|
|
|
$event.preventDefault();
|
2015-08-09 16:36:54 +02:00
|
|
|
}
|
|
|
|
|
2015-12-04 21:00:58 +01:00
|
|
|
function toggleRawSource($event) {
|
2016-05-11 03:23:15 +02:00
|
|
|
if (!vm.showRawSource && !vm.message.$rawSource) {
|
2015-12-04 21:00:58 +01:00
|
|
|
Message.$$resource.post(vm.message.id, "viewsource").then(function(data) {
|
2016-05-11 03:23:15 +02:00
|
|
|
vm.message.$rawSource = data;
|
2015-12-04 21:00:58 +01:00
|
|
|
vm.showRawSource = true;
|
2015-08-04 22:51:33 +02:00
|
|
|
});
|
2015-12-04 21:00:58 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
vm.showRawSource = !vm.showRawSource;
|
|
|
|
}
|
2015-08-04 22:51:33 +02:00
|
|
|
}
|
2016-02-10 22:15:00 +01:00
|
|
|
|
2016-02-26 21:41:53 +01:00
|
|
|
function print($event) {
|
|
|
|
$window.print();
|
|
|
|
}
|
|
|
|
|
2016-02-10 22:15:00 +01:00
|
|
|
function convertToEvent($event) {
|
|
|
|
return convertToComponent($event, 'appointment');
|
|
|
|
}
|
|
|
|
|
|
|
|
function convertToTask($event) {
|
|
|
|
return convertToComponent($event, 'task');
|
|
|
|
}
|
|
|
|
|
|
|
|
function convertToComponent($event, type) {
|
|
|
|
vm.message.$plainContent().then(function(data) {
|
|
|
|
var componentData = {
|
|
|
|
pid: Calendar.$defaultCalendar(),
|
|
|
|
type: type,
|
|
|
|
summary: data.subject,
|
|
|
|
comment: data.content
|
|
|
|
};
|
|
|
|
var component = new Component(componentData);
|
|
|
|
// UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
|
|
|
|
// UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
|
|
|
|
var templateUrl = [
|
|
|
|
sgSettings.activeUser('folderURL'),
|
|
|
|
'Calendar',
|
|
|
|
'UIx' + type.capitalize() + 'EditorTemplate'
|
|
|
|
].join('/');
|
|
|
|
return $mdDialog.show({
|
|
|
|
parent: angular.element(document.body),
|
|
|
|
targetEvent: $event,
|
|
|
|
clickOutsideToClose: true,
|
|
|
|
escapeToClose: true,
|
|
|
|
templateUrl: templateUrl,
|
|
|
|
controller: 'ComponentEditorController',
|
|
|
|
controllerAs: 'editor',
|
|
|
|
locals: {
|
|
|
|
stateComponent: component
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2015-05-06 04:06:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
angular
|
|
|
|
.module('SOGo.MailerUI')
|
|
|
|
.controller('MessageController', MessageController);
|
|
|
|
})();
|