mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-15 03:43:29 +00:00
feat(mail(web)): Templates folder for pre-defined drafts
To create a template, the user needs to: - define a mailbox as the Templates folder; - move a draft to this special folder. Fixes #4320 Fixes #5363
This commit is contained in:
@@ -24,6 +24,7 @@ Mailer_OBJC_FILES += \
|
||||
SOGoDraftsFolder.m \
|
||||
SOGoTrashFolder.m \
|
||||
SOGoJunkFolder.m \
|
||||
SOGoTemplatesFolder.m \
|
||||
\
|
||||
SOGoMailBodyPart.m \
|
||||
SOGoHTMLMailBodyPart.m \
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
@class SOGoSentFolder;
|
||||
@class SOGoTrashFolder;
|
||||
@class SOGoJunkFolder;
|
||||
@class SOGoTemplatesFolder;
|
||||
|
||||
typedef enum {
|
||||
undefined = -1,
|
||||
@@ -63,6 +64,7 @@ typedef enum {
|
||||
SOGoSentFolder *sentFolder;
|
||||
SOGoTrashFolder *trashFolder;
|
||||
SOGoJunkFolder *junkFolder;
|
||||
SOGoTemplatesFolder *templatesFolder;
|
||||
SOGoIMAPAclStyle imapAclStyle;
|
||||
NSMutableArray *identities;
|
||||
NSString *otherUsersFolderName;
|
||||
@@ -117,12 +119,14 @@ typedef enum {
|
||||
- (NSString *) otherUsersFolderNameInContext: (id)_ctx;
|
||||
- (NSString *) sharedFoldersNameInContext: (id)_ctx;
|
||||
- (NSString *) junkFolderNameInContext: (id)_ctx;
|
||||
- (NSString *) templatesFolderNameInContext: (id)_ctx;
|
||||
|
||||
- (SOGoMailFolder *) inboxFolderInContext: (id)_ctx;
|
||||
- (SOGoDraftsFolder *) draftsFolderInContext: (id)_ctx;
|
||||
- (SOGoSentFolder *) sentFolderInContext: (id)_ctx;
|
||||
- (SOGoTrashFolder *) trashFolderInContext: (id)_ctx;
|
||||
- (SOGoJunkFolder *) junkFolderInContext: (id)_ctx;
|
||||
- (SOGoTemplatesFolder *) templatesFolderInContext: (id)_ctx;
|
||||
|
||||
/* namespaces */
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#import "SOGoSentFolder.h"
|
||||
#import "SOGoTrashFolder.h"
|
||||
#import "SOGoJunkFolder.h"
|
||||
#import "SOGoTemplatesFolder.h"
|
||||
#import "SOGoUser+Mailer.h"
|
||||
|
||||
#import "SOGoMailAccount.h"
|
||||
@@ -70,6 +71,7 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
sentFolder = nil;
|
||||
trashFolder = nil;
|
||||
junkFolder = nil;
|
||||
templatesFolder = nil;
|
||||
imapAclStyle = undefined;
|
||||
identities = nil;
|
||||
otherUsersFolderName = nil;
|
||||
@@ -88,6 +90,7 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
[sentFolder release];
|
||||
[trashFolder release];
|
||||
[junkFolder release];
|
||||
[templatesFolder release];
|
||||
[identities release];
|
||||
[otherUsersFolderName release];
|
||||
[sharedFoldersName release];
|
||||
@@ -100,6 +103,11 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) isInTemplatesFolder
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) _appendNamespace: (NSArray *) namespace
|
||||
toFolders: (NSMutableArray *) folders
|
||||
{
|
||||
@@ -406,6 +414,7 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
[self sentFolderNameInContext: context],
|
||||
[self trashFolderNameInContext: context],
|
||||
[self junkFolderNameInContext: context],
|
||||
[self templatesFolderNameInContext: context],
|
||||
nil] stringsWithFormat: @"/%@"];
|
||||
folders = [[self imap4Connection] allFoldersForURL: [self imap4URL]
|
||||
onlySubscribedFolders: subscribedOnly];
|
||||
@@ -479,6 +488,9 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
else if ([flags containsObject: [self junkFolderNameInContext: context]] ||
|
||||
[folderName isEqualToString: [self junkFolderNameInContext: context]])
|
||||
folderType = @"junk";
|
||||
else if ([flags containsObject: [self templatesFolderNameInContext: context]] ||
|
||||
[folderName isEqualToString: [self templatesFolderNameInContext: context]])
|
||||
folderType = @"templates";
|
||||
else if ([folderName isEqualToString: otherUsersFolderName])
|
||||
folderType = @"otherUsers";
|
||||
else if ([folderName isEqualToString: sharedFoldersName])
|
||||
@@ -1012,6 +1024,9 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
else if ([folderName
|
||||
isEqualToString: [self junkFolderNameInContext: _ctx]])
|
||||
klazz = [SOGoJunkFolder class];
|
||||
else if ([folderName
|
||||
isEqualToString: [self templatesFolderNameInContext: _ctx]])
|
||||
klazz = [SOGoTemplatesFolder class];
|
||||
else
|
||||
klazz = [SOGoMailFolder class];
|
||||
|
||||
@@ -1081,6 +1096,11 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
return [self _userFolderNameWithPurpose: @"Junk"];
|
||||
}
|
||||
|
||||
- (NSString *) templatesFolderNameInContext: (id)_ctx
|
||||
{
|
||||
return [self _userFolderNameWithPurpose: @"Templates"];
|
||||
}
|
||||
|
||||
- (NSString *) otherUsersFolderNameInContext: (id)_ctx
|
||||
{
|
||||
return otherUsersFolderName;
|
||||
@@ -1192,6 +1212,19 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
return junkFolder;
|
||||
}
|
||||
|
||||
- (SOGoTemplatesFolder *) templatesFolderInContext: (id) _ctx
|
||||
{
|
||||
if (!templatesFolder)
|
||||
{
|
||||
templatesFolder
|
||||
= [self folderWithTraversal: [self templatesFolderNameInContext: _ctx]
|
||||
andClassName: @"SOGoTemplatesFolder"];
|
||||
[templatesFolder retain];
|
||||
}
|
||||
|
||||
return templatesFolder;
|
||||
}
|
||||
|
||||
/* account delegation */
|
||||
- (NSArray *) delegates
|
||||
{
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
- (SOGoMailAccount *) mailAccountFolder;
|
||||
- (SOGoMailAccounts *) mailAccountsFolder;
|
||||
- (BOOL) isInDraftsFolder;
|
||||
- (BOOL) isInTemplatesFolder;
|
||||
|
||||
/* IMAP4 */
|
||||
|
||||
|
||||
@@ -121,6 +121,11 @@
|
||||
return [container isInDraftsFolder];
|
||||
}
|
||||
|
||||
- (BOOL) isInTemplatesFolder
|
||||
{
|
||||
return [container isInTemplatesFolder];
|
||||
}
|
||||
|
||||
/* IMAP4 */
|
||||
|
||||
- (NGImap4ConnectionManager *) mailManager
|
||||
|
||||
@@ -1144,6 +1144,10 @@ static NSInteger _compareFetchResultsByUID (id entry1, id entry2, NSArray *uids)
|
||||
isEqualToString:
|
||||
[mailAccount junkFolderNameInContext: _ctx]])
|
||||
className = @"SOGoJunkFolder";
|
||||
else if ([fullFolderName
|
||||
isEqualToString:
|
||||
[mailAccount templatesFolderNameInContext: _ctx]])
|
||||
className = @"SOGoTemplatesFolder";
|
||||
/* else if ([folderName isEqualToString:
|
||||
[mailAccount sieveFolderNameInContext: _ctx]])
|
||||
obj = [self lookupFiltersFolder: _key inContext: _ctx]; */
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (C) 2022 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __Mailer_SOGoTemplatesFolder_H__
|
||||
#define __Mailer_SOGoTemplatesFolder_H__
|
||||
|
||||
#import "SOGoDraftsFolder.h"
|
||||
|
||||
@class SOGoDraftsFolder;
|
||||
|
||||
@interface SOGoTemplatesFolder : SOGoDraftsFolder
|
||||
@end
|
||||
|
||||
#endif /* __Mailer_SOGoTemplatesFolder_H__ */
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (C) 2022 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "SOGoTemplatesFolder.h"
|
||||
|
||||
@implementation SOGoTemplatesFolder
|
||||
|
||||
- (BOOL) isInTemplatesFolder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end /* SOGoTemplatesFolder */
|
||||
@@ -115,6 +115,7 @@
|
||||
SOGoDraftsFolderName = "Drafts";
|
||||
SOGoTrashFolderName = "Trash";
|
||||
SOGoJunkFolderName = "Junk";
|
||||
SOGoTemplatesFolderName = "Templates";
|
||||
SOGoMailComposeMessageType = "html";
|
||||
SOGoMailComposeFontSize = "0";
|
||||
SOGoMailDisplayRemoteInlineImages = "never";
|
||||
|
||||
@@ -923,6 +923,8 @@
|
||||
forKey: @"Trash"];
|
||||
[mailboxes setObject: [_defaults junkFolderName]
|
||||
forKey: @"Junk"];
|
||||
[mailboxes setObject: [_defaults templatesFolderName]
|
||||
forKey: @"Templates"];
|
||||
[mailAccount setObject: mailboxes forKey: @"specialMailboxes"];
|
||||
[mailboxes release];
|
||||
|
||||
|
||||
@@ -111,6 +111,9 @@ extern NSString *SOGoWeekStartFirstFullWeek;
|
||||
- (void) setJunkFolderName: (NSString *) newValue;
|
||||
- (NSString *) junkFolderName;
|
||||
|
||||
- (void) setTemplatesFolderName: (NSString *) newValue;
|
||||
- (NSString *) templatesFolderName;
|
||||
|
||||
- (void) setFirstDayOfWeek: (int) newValue;
|
||||
- (int) firstDayOfWeek;
|
||||
|
||||
|
||||
@@ -492,6 +492,17 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
|
||||
stringByEncodingImap4FolderName];
|
||||
}
|
||||
|
||||
- (void) setTemplatesFolderName: (NSString *) newValue
|
||||
{
|
||||
[self setObject: newValue forKey: @"SOGoTemplatesFolderName"];
|
||||
}
|
||||
|
||||
- (NSString *) templatesFolderName
|
||||
{
|
||||
return [[self stringForKey: @"SOGoTemplatesFolderName"]
|
||||
stringByEncodingImap4FolderName];
|
||||
}
|
||||
|
||||
- (void) setFirstDayOfWeek: (int) newValue
|
||||
{
|
||||
[self setInteger: newValue forKey: @"SOGoFirstDayOfWeek"];
|
||||
|
||||
@@ -187,6 +187,7 @@
|
||||
"InboxFolderName" = "Inbox";
|
||||
"DraftsFolderName" = "Drafts";
|
||||
"JunkFolderName" = "Junk";
|
||||
"TemplatesFolderName" = "Templates";
|
||||
"SieveFolderName" = "Filters";
|
||||
"Folders" = "Folders"; /* title line */
|
||||
|
||||
@@ -432,6 +433,9 @@
|
||||
"Set as Sent" = "Set as Sent";
|
||||
"Set as Trash" = "Set as Trash";
|
||||
|
||||
/* Set the folder as the one holding the Templates */
|
||||
"Set as Templates" = "Set as Templates";
|
||||
|
||||
/* Set the folder as the one holding Junk mails */
|
||||
"Set as Junk" = "Set as Junk";
|
||||
|
||||
@@ -454,6 +458,9 @@
|
||||
"Your email has been sent" = "Your email has been sent";
|
||||
"Folder compacted" = "Folder compacted";
|
||||
|
||||
"New draft" = "New draft";
|
||||
"Create new draft with this template" = "Create new draft with this template";
|
||||
|
||||
/* Advanced search */
|
||||
"Enter Subject" = "Enter Subject";
|
||||
"Enter From" = "Enter From";
|
||||
|
||||
@@ -118,6 +118,36 @@
|
||||
andString: [data jsonRepresentation]];
|
||||
}
|
||||
|
||||
- (WOResponse *) composeAction
|
||||
{
|
||||
SOGoMailAccount *account;
|
||||
SOGoMailObject *co;
|
||||
SOGoDraftsFolder *drafts;
|
||||
SOGoDraftObject *newMail;
|
||||
NSString *accountName, *mailboxName, *messageName;
|
||||
NSDictionary *data;
|
||||
|
||||
co = [self clientObject];
|
||||
account = [co mailAccountFolder];
|
||||
drafts = [account draftsFolderInContext: context];
|
||||
newMail = [drafts newDraft];
|
||||
[newMail fetchMailForEditing: co];
|
||||
[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", nil];
|
||||
|
||||
return [self responseWithStatus: 201
|
||||
andString: [data jsonRepresentation]];
|
||||
}
|
||||
|
||||
- (WOResponse *) viewPlainAction
|
||||
{
|
||||
BOOL htmlContent;
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
}
|
||||
|
||||
- (BOOL) mailIsDraft;
|
||||
- (BOOL) mailIsTemplate;
|
||||
- (NSNumber *) shouldAskReceipt;
|
||||
- (NSString *) formattedDate;
|
||||
- (NSString *) _matchingIdentityEMailOrDefault: (BOOL) useDefault;
|
||||
@@ -340,6 +341,7 @@ static NSString *mailETag = nil;
|
||||
data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
[self shouldAskReceipt], @"shouldAskReceipt",
|
||||
[NSNumber numberWithBool: [self mailIsDraft]], @"isDraft",
|
||||
[NSNumber numberWithBool: [self mailIsTemplate]], @"isTemplate",
|
||||
renderedPart, @"parts",
|
||||
nil];
|
||||
if ([self formattedDate])
|
||||
@@ -803,6 +805,11 @@ static NSString *mailETag = nil;
|
||||
return [[self clientObject] isInDraftsFolder];
|
||||
}
|
||||
|
||||
- (BOOL) mailIsTemplate
|
||||
{
|
||||
return [[self clientObject] isInTemplatesFolder];
|
||||
}
|
||||
|
||||
- (id) redirectToParentFolder
|
||||
{
|
||||
id url;
|
||||
|
||||
@@ -119,6 +119,11 @@
|
||||
actionClass = "UIxMailFolderActions";
|
||||
actionName = "setAsJunkFolder";
|
||||
};
|
||||
setAsTemplatesFolder = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailFolderActions";
|
||||
actionName = "setAsTemplatesFolder";
|
||||
};
|
||||
markMessagesAsJunk = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailFolderActions";
|
||||
@@ -237,6 +242,11 @@
|
||||
actionClass = "UIxMailActions";
|
||||
actionName = "edit";
|
||||
};
|
||||
compose = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailActions";
|
||||
actionName = "compose";
|
||||
};
|
||||
reply = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailActions";
|
||||
|
||||
@@ -60,7 +60,9 @@
|
||||
<div ng-message="required">This field is required</div>
|
||||
</div>
|
||||
</md-autocomplete>
|
||||
<md-button class="sg-icon-button" ng-click="editor.send()"
|
||||
<md-button class="sg-icon-button"
|
||||
ng-click="editor.send()"
|
||||
ng-hide="editor.saveAsTemplate"
|
||||
ng-disabled="!(editor.message.editable.to.length > 0 || editor.message.editable.cc.length > 0 || editor.message.editable.bcc.length > 0) || editor.uploader.isUploading || messageForm.$invalid || messageForm.$submitted"
|
||||
sg-ripple-click="mailEditor">
|
||||
<md-icon>send</md-icon>
|
||||
|
||||
@@ -274,6 +274,11 @@
|
||||
<var:string label:value="Set as Junk"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-show="::$menuCtrl.folder.$canFolderAs()">
|
||||
<md-button type="button" ng-click="$menuCtrl.setFolderAs('Templates')">
|
||||
<var:string label:value="Set as Templates"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-divider ng-show="::($menuCtrl.folder.type != 'additional')"><!-- divider --></md-divider>
|
||||
<md-menu-item ng-show="::($menuCtrl.folder.type != 'additional')">
|
||||
<md-button type="button" ng-click="$menuCtrl.share()">
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
</div>
|
||||
<div class="msg-recipients" layout="column" flex="50" flex-xs="100">
|
||||
<!-- to -->
|
||||
<div class="pseudo-input-container--compact" ng-show="::viewer.message.to.length > 0">
|
||||
<div class="pseudo-input-container--compact" ng-show="viewer.message.to.length > 0">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="To"/>
|
||||
</label>
|
||||
@@ -255,9 +255,20 @@
|
||||
</md-chips>
|
||||
</div>
|
||||
|
||||
<!-- New draft from template -->
|
||||
<div class="hide-print" ng-show="viewer.message.isTemplate">
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
<md-list-item class="md-clickable" layout="row" layout-align="space-between center"
|
||||
label:aria-label="New draft"
|
||||
ng-click="viewer.compose($event)">
|
||||
<md-icon>drafts</md-icon>
|
||||
<p><var:string label:value="Create new draft with this template"/></p>
|
||||
</md-list-item>
|
||||
</div>
|
||||
|
||||
<!-- S/MIME Signature -->
|
||||
<sg-block-toggle class="hide-print" layout="column"
|
||||
ng-show="::viewer.message.signed">
|
||||
ng-show="viewer.message.signed">
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
<md-list-item class="sg-button-toggle">
|
||||
<div>
|
||||
|
||||
@@ -134,8 +134,10 @@ String.prototype.formatted = function() {
|
||||
return newString;
|
||||
};
|
||||
|
||||
String.prototype.isValidEmail = function() {
|
||||
var emailRE = /^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i;
|
||||
String.prototype.isValidEmail = function(strict) {
|
||||
var emailRE = strict ?
|
||||
/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i : /([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)/i;
|
||||
|
||||
return emailRE.test(this);
|
||||
};
|
||||
|
||||
|
||||
@@ -203,6 +203,10 @@
|
||||
this.$displayName = l('JunkFolderName');
|
||||
this.$icon = 'thumb_down';
|
||||
}
|
||||
else if (this.type == 'templates') {
|
||||
this.$displayName = l('TemplatesFolderName');
|
||||
this.$icon = 'mail_outline';
|
||||
}
|
||||
else if (this.type == 'additional') {
|
||||
this.$icon = 'folder';
|
||||
}
|
||||
|
||||
@@ -776,10 +776,20 @@
|
||||
return this.$newDraft('forward');
|
||||
};
|
||||
|
||||
/**
|
||||
* @function $compose
|
||||
* @memberof Message.prototype
|
||||
* @desc Prepare a new Message object as a new draft from a copy of this message.
|
||||
* @returns a promise of the HTTP operations
|
||||
*/
|
||||
Message.prototype.$compose = function() {
|
||||
return this.$newDraft('compose');
|
||||
};
|
||||
|
||||
/**
|
||||
* @function $newDraft
|
||||
* @memberof Message.prototype
|
||||
* @desc Prepare a new Message object as a reply or a forward of the current message and associated
|
||||
* @desc Prepare a new Message object as a reply, a forward or a copy of the current message and associated
|
||||
* to the draft mailbox.
|
||||
* @see {@link Account.$newMessage}
|
||||
* @see {@link Message.$editableContent}
|
||||
|
||||
@@ -479,6 +479,12 @@
|
||||
}
|
||||
};
|
||||
|
||||
this.compose = function($event) {
|
||||
if (!this._showMailEditorInPopup('compose')) {
|
||||
_showMailEditor($event, this.message.$compose());
|
||||
}
|
||||
};
|
||||
|
||||
this.openInPopup = function(action) {
|
||||
var url = [sgSettings.baseURL(),
|
||||
'UIxMailPopupView#!/Mail',
|
||||
|
||||
@@ -304,7 +304,6 @@
|
||||
|
||||
this.addRecipient = function (contact, field) {
|
||||
var recipients, recipient, list, i, address;
|
||||
var emailRE = /([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)/i;
|
||||
|
||||
recipients = this.message.editable[field];
|
||||
|
||||
@@ -319,7 +318,7 @@
|
||||
contact.charCodeAt(i) == 32 || // space
|
||||
contact.charCodeAt(i) == 44 || // ,
|
||||
contact.charCodeAt(i) == 59) && // ;
|
||||
emailRE.test(address) &&
|
||||
address.isValidEmail() &&
|
||||
recipients.indexOf(address) < 0) {
|
||||
recipients.push(address);
|
||||
address = '';
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
// this.service = Message;
|
||||
this.MailboxService = Mailbox;
|
||||
|
||||
if (Mailbox.selectedFolder.type == 'draft')
|
||||
if (Mailbox.selectedFolder.type == 'draft' || Mailbox.selectedFolder.type == 'templates')
|
||||
watchedAttrs.push('subject');
|
||||
|
||||
$scope.$watch(
|
||||
|
||||
Reference in New Issue
Block a user