diff --git a/UI/MailerUI/UIxMailAccountActions.m b/UI/MailerUI/UIxMailAccountActions.m index e331ab4ab..7c6c103e8 100644 --- a/UI/MailerUI/UIxMailAccountActions.m +++ b/UI/MailerUI/UIxMailAccountActions.m @@ -72,9 +72,11 @@ - (WOResponse *) composeAction { - NSString *urlBase, *url, *value, *signature, *nl; + NSString *value, *signature, *nl; SOGoDraftObject *newDraftMessage; NSMutableDictionary *headers; + NSDictionary *data; + NSString *accountName, *mailboxName, *messageName; SOGoDraftsFolder *drafts; id mailTo; BOOL save; @@ -118,12 +120,16 @@ if (save) [newDraftMessage storeInfo]; - urlBase = [newDraftMessage baseURLInContext: context]; - url = [urlBase composeURLWithAction: @"edit" - parameters: nil - andHash: NO]; + accountName = [[self clientObject] nameInContainer]; + mailboxName = [drafts relativeImap4Name]; + messageName = [newDraftMessage nameInContainer]; + data = [NSDictionary dictionaryWithObjectsAndKeys: + accountName, @"accountId", + mailboxName, @"mailboxPath", + messageName, @"uid", nil]; - return [self redirectToLocation: url]; + return [self responseWithStatus: 201 + andString: [data jsonRepresentation]]; } - (WOResponse *) _performDelegationAction: (SEL) action diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m index a9bf3a65c..0a73f92ad 100644 --- a/UI/MailerUI/UIxMailEditor.m +++ b/UI/MailerUI/UIxMailEditor.m @@ -54,6 +54,7 @@ #import #import #import +#import #import #import #import @@ -83,7 +84,7 @@ NSString *sourceFolder; NSString *text; NSMutableArray *fromEMails; - NSString *from; + NSDictionary *from; SOGoMailFolder *sentFolder; BOOL isHTML; @@ -112,7 +113,8 @@ static NSArray *infoKeys = nil; @"subject", @"to", @"cc", @"bcc", @"from", @"inReplyTo", @"replyTo", - @"priority", @"receipt", nil]; + @"priority", @"receipt", + @"content", nil]; } - (id) init @@ -217,6 +219,11 @@ static NSArray *infoKeys = nil; return [[ud mailComposeMessageType] isEqualToString: @"html"]; } +- (NSString *) editorClass +{ + return ([self isHTML]? @"ck-editor" : @"plain-text"); +} + - (NSString *) itemPriorityText { return [self labelForKey: [NSString stringWithFormat: @"%@", [item lowercaseString]]]; @@ -246,20 +253,21 @@ static NSArray *infoKeys = nil; ASSIGN (from, newFrom); } -- (NSString *) _emailFromIdentity: (NSDictionary *) identity +- (NSDictionary *) _emailFromIdentity: (NSDictionary *) identity { - NSString *fullName, *format; + static NSArray *keys = nil; - fullName = [identity objectForKey: @"fullName"]; - if ([fullName length]) - format = @"%{fullName} <%{email}>"; - else - format = @"%{email}"; + if (!keys) + { + keys = [NSArray arrayWithObjects: @"email", @"fullName", nil]; + [keys retain]; + } - return [identity keysWithFormat: format]; + return [NSDictionary dictionaryWithObjects: [identity objectsForKeys: keys notFoundMarker: [NSNull null]] + forKeys: [NSArray arrayWithObjects: @"email", @"name", nil]]; } -- (NSString *) from +- (NSDictionary *) from { NSDictionary *identity; @@ -412,7 +420,7 @@ static NSArray *infoKeys = nil; { NSArray *identities; int count, max; - NSString *email; + NSDictionary *email; SOGoMailAccount *account; if (!fromEMails) @@ -423,8 +431,7 @@ static NSArray *infoKeys = nil; fromEMails = [[NSMutableArray alloc] initWithCapacity: max]; for (count = 0; count < max; count++) { - email - = [self _emailFromIdentity: [identities objectAtIndex: count]]; + email = [self _emailFromIdentity: [identities objectAtIndex: count]]; [fromEMails addObjectUniquely: email]; } } @@ -443,79 +450,91 @@ static NSArray *infoKeys = nil; - (NSDictionary *) storeInfo { - [self debugWithFormat:@"storing info ..."]; - return [self dictionaryWithValuesForKeys: infoKeys]; + WORequest *request; + NSDictionary *params, *filteredParams; + + request = [context request]; + params = [[request contentAsString] objectFromJSONString]; + filteredParams = [NSDictionary dictionaryWithObjects: [params objectsForKeys: infoKeys notFoundMarker: [NSNull null]] + forKeys: infoKeys]; + + [self setTo: [filteredParams objectForKey: @"to"]]; + [self setCc: [filteredParams objectForKey: @"cc"]]; + [self setBcc: [filteredParams objectForKey: @"bcc"]]; + [self setText: [filteredParams objectForKey: @"content"]]; + + return filteredParams; } /* contacts search */ -- (NSArray *) contactFolders -{ - SOGoContactFolders *folderContainer; +// - (NSArray *) contactFolders +// { +// SOGoContactFolders *folderContainer; - folderContainer = (SOGoContactFolders *) [[[self clientObject] lookupUserFolder] privateContacts: @"Contacts" - inContext: nil]; +// folderContainer = (SOGoContactFolders *) [[[self clientObject] lookupUserFolder] privateContacts: @"Contacts" +// inContext: nil]; - return [folderContainer subFolders]; -} +// return [folderContainer subFolders]; +// } -- (NSArray *) personalContactInfos -{ - SOGoContactFolders *folderContainer; - id folder; - NSArray *contactInfos; +// - (NSArray *) personalContactInfos +// { +// SOGoContactFolders *folderContainer; +// id folder; +// NSArray *contactInfos; - folderContainer = (SOGoContactFolders *) [[[self clientObject] lookupUserFolder] privateContacts: @"Contacts" - inContext: nil]; +// folderContainer = (SOGoContactFolders *) [[[self clientObject] lookupUserFolder] privateContacts: @"Contacts" +// inContext: nil]; - folder = [folderContainer lookupPersonalFolder: @"personal" ignoringRights: YES]; +// folder = [folderContainer lookupPersonalFolder: @"personal" ignoringRights: YES]; - // If the folder doesn't exist anymore or if the database is down, we - // return an empty array. - if ([folder isKindOfClass: [NSException class]]) - return [NSArray array]; +// // If the folder doesn't exist anymore or if the database is down, we +// // return an empty array. +// if ([folder isKindOfClass: [NSException class]]) +// return [NSArray array]; - contactInfos = [folder lookupContactsWithFilter: nil - onCriteria: nil - sortBy: @"c_cn" - ordering: NSOrderedAscending - inDomain: nil]; +// contactInfos = [folder lookupContactsWithFilter: nil +// onCriteria: nil +// sortBy: @"c_cn" +// ordering: NSOrderedAscending +// inDomain: nil]; - return contactInfos; -} +// return contactInfos; +// } -- (void) setCurrentFolder: (id) _currentFolder -{ - ASSIGN (currentFolder, _currentFolder); -} +// - (void) setCurrentFolder: (id) _currentFolder +// { +// ASSIGN (currentFolder, _currentFolder); +// } -- (NSString *) currentContactFolderId -{ - return [NSString stringWithFormat: @"/%@", [currentFolder nameInContainer]]; -} +// - (NSString *) currentContactFolderId +// { +// return [NSString stringWithFormat: @"/%@", [currentFolder nameInContainer]]; +// } -- (NSString *) currentContactFolderName -{ - return [currentFolder displayName]; -} +// - (NSString *) currentContactFolderName +// { +// return [currentFolder displayName]; +// } -- (NSString *) currentContactFolderOwner -{ - return [currentFolder ownerInContext: context]; -} +// - (NSString *) currentContactFolderOwner +// { +// return [currentFolder ownerInContext: context]; +// } -- (NSString *) currentContactFolderClass -{ - return ([currentFolder isKindOfClass: [SOGoContactSourceFolder class]] - ? @"remote" : @"local"); -} +// - (NSString *) currentContactFolderClass +// { +// return ([currentFolder isKindOfClass: [SOGoContactSourceFolder class]] +// ? @"remote" : @"local"); +// } /* requests */ -- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request - inContext: (WOContext*) localContext -{ - return YES; -} +// - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request +// inContext: (WOContext*) localContext +// { +// return YES; +// } /* actions */ - (NSString *) _fixedFilename: (NSString *) filename @@ -687,9 +706,12 @@ static NSArray *infoKeys = nil; return [[self attachmentAttrs] count] > 0 ? YES : NO; } -- (id) defaultAction +- (id ) editAction { + id response; SOGoDraftObject *co; + NSMutableDictionary *data; + id value; co = [self clientObject]; [co fetchInfo]; @@ -698,13 +720,37 @@ static NSArray *infoKeys = nil; [self setSourceUID: [co IMAP4ID]]; [self setSourceFolder: [co sourceFolder]]; - return self; + data = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSArray arrayWithObject: [self from]], @"from", + [self localeCode], @"locale", + text, @"content", + nil]; + if ((value = [self replyTo])) + [data setObject: value forKey: @"replyTo"]; + if ((value = [self to])) + [data setObject: value forKey: @"to"]; + if ((value = [self cc])) + [data setObject: value forKey: @"cc"]; + if ((value = [self bcc])) + [data setObject: value forKey: @"bcc"]; + if ((value = [self subject])) + [data setObject: value forKey: @"subject"]; + if ((value = [self attachmentAttrs])) + [data setObject: value forKey: @"attachmentAttrs"]; + // [self shouldAskReceipt], @"shouldAskReceipt", + // [NSNumber numberWithBool: [self mailIsDraft]], @"isDraft", + response = [self responseWithStatus: 200 + andString: [data jsonRepresentation]]; + + return response; } -- (id ) saveAction +- (WOResponse *) saveAction { id result; + NSArray *attrs; + [self setIsHTML: [self isHTML]]; result = [self _saveFormInfo]; if (!result) { @@ -713,7 +759,7 @@ static NSArray *infoKeys = nil; if (!result) { attachmentAttrs = nil; - NSArray *attrs = [self attachmentAttrs]; + attrs = [self attachmentAttrs]; result = [self responseWithStatus: 200 andString: [attrs jsonRepresentation]]; } @@ -790,10 +836,10 @@ static NSArray *infoKeys = nil; co = [self clientObject]; /* first, save form data */ - error = [self validateForSend]; + error = [self _saveFormInfo]; if (!error) { - error = [self _saveFormInfo]; + error = [self validateForSend]; if (!error) error = [co sendMail]; else diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 4515eac4f..0fbb16314 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -234,9 +234,9 @@ SOGoMailFolder *co; SOGoMailAccount *account; SOGoUserSettings *us; + WORequest *request; WOResponse *response; - NSArray *uids; - NSString *value; + id uids; NSDictionary *data; BOOL withTrash; NSMutableDictionary *moduleSettings, *threadsCollapsed; @@ -244,14 +244,14 @@ NSMutableArray *mailboxThreadsCollapsed; int i; - co = [self clientObject]; - value = [[context request] formValueForKey: @"uid"]; - withTrash = ![[[context request] formValueForKey: @"withoutTrash"] boolValue]; response = nil; + request = [context request]; + co = [self clientObject]; + data = [[request contentAsString] objectFromJSONString]; + withTrash = ![[data objectForKey: @"withoutTrash"] boolValue]; - if ([value length] > 0) + if ((uids = [data objectForKey: @"uids"]) && [uids isKindOfClass: [NSArray class]] && [uids length] > 0) { - uids = [value componentsSeparatedByString: @","]; response = (WOResponse *) [co deleteUIDs: uids useTrashFolder: &withTrash inContext: context]; if (!response) { @@ -289,7 +289,8 @@ else { response = [self responseWithStatus: 500]; - [response appendContentString: @"Missing 'uid' parameter."]; + data = [NSDictionary dictionaryWithObject: @"Missing 'uids' parameter." forKey: @"error"]; + [response appendContentString: [data jsonRepresentation]]; } return response; diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index 313e4005f..807fe797e 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -51,6 +51,8 @@ #import #import #import +#import +#import #import #import #import // cyclic @@ -275,12 +277,13 @@ static NSString *mailETag = nil; data = [NSMutableDictionary dictionaryWithObjectsAndKeys: [self formattedDate], @"date", - [self messageSubject], @"subject", [self attachmentAttrs], @"attachmentAttrs", [self shouldAskReceipt], @"shouldAskReceipt", [NSNumber numberWithBool: [self mailIsDraft]], @"isDraft", [[self generateResponse] contentAsString], @"content", nil]; + if ([self messageSubject]) + [data setObject: [self messageSubject] forKey: @"subject"]; if ((addresses = [addressFormatter dictionariesForArray: [co fromEnvelopeAddresses]])) [data setObject: addresses forKey: @"from"]; if ((addresses = [addressFormatter dictionariesForArray: [co toEnvelopeAddresses]])) @@ -292,6 +295,20 @@ static NSString *mailETag = nil; if ((addresses = [addressFormatter dictionariesForArray: [co replyToEnvelopeAddresses]])) [data setObject: addresses forKey: @"reply-to"]; + if ([self mailIsDraft]) + { + SOGoMailAccount *account; + SOGoDraftsFolder *folder; + SOGoDraftObject *newMail; + + account = [co mailAccountFolder]; + folder = [account draftsFolderInContext: context]; + newMail = [folder newDraft]; + [newMail fetchMailForEditing: co]; + [newMail storeInfo]; + [data setObject: [newMail nameInContainer] forKey: @"draftId"]; + } + response = [self responseWithStatus: 200 andString: [data jsonRepresentation]]; diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index fa06462d4..163a4ad27 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -337,6 +337,10 @@ protectedBy = "View"; pageName = "UIxMailSearch"; }; + editorTemplate = { + protectedBy = "View"; + pageName = "UIxMailEditor"; + }; }; }; @@ -388,13 +392,10 @@ }; }; methods = { - view = { - protectedBy = "View"; - pageName = "UIxMailEditor"; - }; edit = { protectedBy = "View"; pageName = "UIxMailEditor"; + actionName = "edit"; }; save = { protectedBy = "View"; diff --git a/UI/Templates/MailerUI/UIxMailEditor.wox b/UI/Templates/MailerUI/UIxMailEditor.wox index 51a3e0afc..47e4970f3 100644 --- a/UI/Templates/MailerUI/UIxMailEditor.wox +++ b/UI/Templates/MailerUI/UIxMailEditor.wox @@ -1,131 +1,30 @@ - - - - - -
-
-
- - - - - - - -
-
- - - - -
- : -
-
- + + + +
+ + + + +