Skip to content

Commit

Permalink
feat(mail(web)): forward multiple messages as attachments
Browse files Browse the repository at this point in the history
Fixes #33
  • Loading branch information
cgx committed Feb 18, 2022
1 parent a98b404 commit c476503
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 38 deletions.
99 changes: 98 additions & 1 deletion UI/MailerUI/UIxMailFolderActions.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* UIxMailFolderActions.m - this file is part of SOGo
*
* Copyright (C) 2007-2021 Inverse inc.
* Copyright (C) 2007-2022 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -30,11 +30,15 @@
#import <NGImap4/NSString+Imap4.h>


#import <Mailer/SOGoDraftObject.h>
#import <Mailer/SOGoDraftsFolder.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailFolder.h>
#import <Mailer/SOGoMailObject+Draft.h>
#import <Mailer/SOGoTrashFolder.h>

#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSObject+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
Expand Down Expand Up @@ -704,6 +708,99 @@ - (WOResponse *) moveMessagesAction
return response;
}

- (WOResponse *) forwardMessagesAction
{
BOOL htmlComposition;
NSArray *uids;
NSDictionary *data, *identity, *headers;
NSMutableDictionary *attachment;
NSString *accountName, *mailboxName, *messageName, *fullName, *format, *signature, *nl, *space;
SOGoDraftObject *newMail;
SOGoDraftsFolder *drafts;
SOGoMailAccount *account;
SOGoMailFolder *co;
SOGoMailObject *currentMail;
SOGoUserDefaults *ud;
WOResponse *response;
unsigned int i;

co = [self clientObject];
data = [[[context request] contentAsString] objectFromJSONString];
uids = [data objectForKey: @"uids"];
response = nil;

if ([uids count] > 0)
{
account = [co mailAccountFolder];
identity = [account defaultIdentity];
drafts = [account draftsFolderInContext: context];
newMail = [drafts newDraft];
ud = [[context activeUser] userDefaults];
htmlComposition = [[ud mailComposeMessageType] isEqualToString: @"html"];

[newMail setIsHTML: htmlComposition];
if (identity)
{
// Set From header
fullName = [identity objectForKey: @"fullName"];
if ([fullName length])
format = @"%{fullName} <%{email}>";
else
format = @"%{email}";
headers = [NSDictionary dictionaryWithObject: [identity keysWithFormat: format]
forKey: @"from"];
[newMail setHeaders: headers];

// Add signature
signature = [identity objectForKey: @"signature"];
if ([signature length])
{
nl = (htmlComposition? @"<br />" : @"\n");
space = (htmlComposition ? @"&nbsp;" : @" ");
[newMail setText: [NSString stringWithFormat: @"%@%@--%@%@%@", nl, nl, space, nl, signature]];
}
}

for (i = 0; i < [uids count]; i++)
{
currentMail = [co lookupName: [NSString stringWithFormat: @"%@", [uids objectAtIndex: i]]
inContext: context
acquire: NO];
attachment = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[currentMail filenameForForward], @"filename",
@"message/rfc822", @"mimetype",
nil];
[newMail saveAttachment: [currentMail content]
withMetadata: attachment];
}

[newMail save]; // store on IMAP server
[newMail storeInfo];

accountName = [account nameInContainer];
mailboxName = [drafts absoluteImap4Name];
mailboxName = [mailboxName substringWithRange: NSMakeRange(1, [mailboxName length] - 2)];
messageName = [newMail nameInContainer];

data = [NSDictionary dictionaryWithObjectsAndKeys:
accountName, @"accountId",
mailboxName, @"mailboxPath",
messageName, @"draftId",
[NSNumber numberWithInt: [newMail IMAP4ID]], @"uid", nil];

return [self responseWithStatus: 201
andString: [data jsonRepresentation]];
}
else
{
data = [NSDictionary dictionaryWithObject: [self labelForKey: @"Error forwarding messages." inContext: context]
forKey: @"message"];
response = [self responseWithStatus: 500 andJSONRepresentation: data];
}

return response;
}

- (void) _setFolderPurposeOnMainAccount: (NSString *) purpose
inUserDefaults: (SOGoUserDefaults *) ud
to: (NSString *) value
Expand Down
5 changes: 5 additions & 0 deletions UI/MailerUI/product.plist
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@
actionClass = "UIxMailFolderActions";
actionName = "moveMessages";
};
forwardMessages = {
protectedBy = "View";
actionClass = "UIxMailFolderActions";
actionName = "forwardMessages";
};
setAsDraftsFolder = {
protectedBy = "View";
actionClass = "UIxMailFolderActions";
Expand Down
5 changes: 5 additions & 0 deletions UI/Templates/MailerUI/UIxMailFolderTemplate.wox
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@
<var:string label:value="Mark as Read"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="mailbox.forwardSelectedMessages($event)">
<var:string label:value="Forward"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="mailbox.selectedFolder.saveSelectedMessages()">
<var:string label:value="Save As..."/>
Expand Down
17 changes: 17 additions & 0 deletions UI/WebServerResources/js/Mailer/Mailbox.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,23 @@
});
};

/**
* @function forwardMessages
* @memberof Mailbox.prototype
* @desc Attach multiple messages to a new draft
* @returns a promise of the HTTP operation with the draft coordinates
*/
Mailbox.prototype.forwardMessages = function(messages) {
var _this = this,
uids = _.map(messages, 'uid');

return Mailbox.$$resource.post(this.id, 'forwardMessages', { uids: uids }).then(function(data) {
Mailbox.$log.debug('Forward selected messages: ' + JSON.stringify(data, undefined, 2));
var message = new Mailbox.$Message(data.accountId, _this.$account.$getMailboxByPath(data.mailboxPath), data);
return message;
});
};

/**
* @function saveSelectedMessages
* @memberof Mailbox.prototype
Expand Down
121 changes: 87 additions & 34 deletions UI/WebServerResources/js/Mailer/MailboxController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
var vm = this,
defaultWindowTitle = angular.element($window.document).find('title').attr('sg-default') || "SOGo",
hotkeys = [],
sortLabels;
sortLabels,
popupWindow = null;

sortLabels = {
subject: 'Subject',
Expand Down Expand Up @@ -184,15 +185,58 @@
return Preferences.defaults.SOGoMailComposeWindowEnabled;
};

this.newMessage = function($event, inPopup) {
var message, onCompleteDeferred = $q.defer();
this.openInPopup = function(message, action) {
var url = [sgSettings.baseURL(),
'UIxMailPopupView#!/Mail',
this.account.id],
wId = this.account.id + '/' + Math.random(0, 1000);
if (message) {
// The double-encoding is necessary
url.push(encodeUriFilter(encodeUriFilter(message.$mailbox.path)));
url.push(message.uid);
wId = message.$absolutePath();
}
if (action) {
wId += '/' + action;
url.push(action);
}
url = url.join('/');
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(','));
};

if (vm.messageDialog === null) {
if (inPopup || Preferences.defaults.SOGoMailComposeWindow == 'popup')
_newMessageInPopup();
else {
message = vm.account.$newMessage();
vm.messageDialog = $mdDialog
this.closePopup = function() {
if ($window.document.body.classList.contains('popup'))
$window.close();
};

/**
* To keep track of the currently active dialog, we share a common variable with the parent controller.
*/
function _messageDialog() {
if ($scope.mailbox) {
if (arguments.length > 0)
$scope.mailbox.messageDialog = arguments[0];
return $scope.mailbox.messageDialog;
}
return null;
}

function _showMailEditor($event, message) {
if (_messageDialog() === null) {
var onCompleteDeferred = $q.defer();
_messageDialog(
$mdDialog
.show({
parent: angular.element(document.body),
targetEvent: $event,
Expand All @@ -215,34 +259,29 @@
})
.catch(_.noop) // Cancel
.finally(function() {
vm.messageDialog = null;
});
}
_messageDialog(null);
vm.closePopup();
})
);
}
}

this._showMailEditorInPopup = function(message, action, inPopup) {
if (!sgSettings.isPopup &&
(Preferences.defaults.SOGoMailComposeWindow == 'popup' || inPopup)) {
this.openInPopup(message, action);
return true;
}
return false;
};

function _newMessageInPopup() {
var url = [sgSettings.baseURL(),
'UIxMailPopupView#!/Mail',
vm.account.id,
// The double-encoding is necessary
encodeUriFilter(encodeUriFilter(vm.selectedFolder.path)),
'new']
.join('/'),
wId = vm.selectedFolder.$id() + '/' + Math.random(0, 1000);
$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(','));
}
this.newMessage = function($event, inPopup) {
if (!this._showMailEditorInPopup(null, 'new', inPopup)) {
this.account.$newMessage().then(function(message) {
_showMailEditor($event, message);
});
}
};

/**
* User has pressed up arrow key
Expand Down Expand Up @@ -579,6 +618,20 @@
}
};

this.forwardSelectedMessages = function($event) {
var _this = this,
selectedMessages = vm.selectedFolder.selectedMessages();
if (_.size(selectedMessages) > 0) {
vm.selectedFolder.forwardMessages(selectedMessages).then(function(message) {
if (!_this._showMailEditorInPopup(message, 'edit')) {
message.$editableContent().then(function() {
_showMailEditor($event, message);
});
}
});
}
};

}

angular
Expand Down
8 changes: 5 additions & 3 deletions UI/WebServerResources/js/Mailer/Mailer.popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
stateMailbox: stateMailbox
}
})
.state('mail.account.mailbox.newMessage', {
.state('mail.account.newMessage', {
url: '/new',
views: {
'message@': {
Expand Down Expand Up @@ -91,7 +91,7 @@
});

// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/Mail/0/folderINBOX/new');
$urlRouterProvider.otherwise('/Mail/0/new');
}

/**
Expand Down Expand Up @@ -199,7 +199,9 @@
}
else {
futureMailbox = stateAccount.$getMailboxes().then(function(mailboxes) {
return _find(mailboxes);
var data = _find(mailboxes),
mailbox = new Mailbox(stateAccount, data);
return mailbox;
});
}

Expand Down

0 comments on commit c476503

Please sign in to comment.