Allow a mailbox to be deleted immediately

Fixes #3875
pull/225/head
Francis Lachapelle 2016-11-01 11:40:59 -04:00
parent 5c7147cccc
commit 0e0f53cd98
6 changed files with 116 additions and 60 deletions

1
NEWS
View File

@ -3,6 +3,7 @@
Enhancements Enhancements
- [web] add constraints to start/end dates of automatic responder (#3841) - [web] add constraints to start/end dates of automatic responder (#3841)
- [web] allow a mailbox to be deleted immediately (#3875)
- [web] updated Angular to version 1.5.8 - [web] updated Angular to version 1.5.8
- [eas] initial support for recurring tasks EAS - [eas] initial support for recurring tasks EAS
- [eas] now support replied/forwarded flags using EAS (#3796) - [eas] now support replied/forwarded flags using EAS (#3796)

View File

@ -269,6 +269,10 @@
"quotasFormat" = "%{0}% used on %{1} MB"; "quotasFormat" = "%{0}% used on %{1} MB";
"Unable to move/delete folder." = "Unable to move/delete folder."; "Unable to move/delete folder." = "Unable to move/delete folder.";
/* Alternative operation when folder cannot be deleted */
"The mailbox could not be moved to the trash folder. Would you like to delete it immediately?"
= "The mailbox could not be moved to the trash folder. Would you like to delete it immediately?";
/* Confirmation message when deleting multiple messages */ /* Confirmation message when deleting multiple messages */
"Are you sure you want to delete the selected messages?" = "Are you sure you want to delete the selected messages?"; "Are you sure you want to delete the selected messages?" = "Are you sure you want to delete the selected messages?";

View File

@ -212,42 +212,106 @@
return destURL; return destURL;
} }
- (WOResponse *) deleteAction - (void) _removeFolder
{ {
NSString *currentMailbox, *currentAccount, *keyForMsgUIDs;
NSMutableDictionary *moduleSettings, *threadsCollapsed;
NGImap4Connection *connection; NGImap4Connection *connection;
SOGoMailFolder *co, *inbox; NSMutableDictionary *moduleSettings, *threadsCollapsed;;
NSDictionary *jsonResponse; NSString *keyForMsgUIDs, *currentMailbox, *currentAccount;
NSURL *srcURL, *destURL; NSURL *srcURL;
SOGoMailFolder *co;
SOGoUserSettings *us; SOGoUserSettings *us;
WOResponse *response;
NSException *error;
BOOL moved;
co = [self clientObject]; co = [self clientObject];
srcURL = [co imap4URL];
connection = [co imap4Connection];
// Unsubscribe from mailbox
[[connection client] unsubscribe: [srcURL path]];
// Verify if the current folder have any collapsed threads save under it name and erase it
us = [[context activeUser] userSettings];
moduleSettings = [us objectForKey: @"Mail"];
threadsCollapsed = [moduleSettings objectForKey: @"threadsCollapsed"];
if (threadsCollapsed)
{
currentMailbox = [co nameInContainer];
currentAccount = [[co container] nameInContainer];
keyForMsgUIDs = [NSString stringWithFormat:@"/%@/%@", currentAccount, currentMailbox];
if ([threadsCollapsed objectForKey: keyForMsgUIDs])
{
[threadsCollapsed removeObjectForKey: keyForMsgUIDs];
[us synchronize];
}
}
}
- (WOResponse *) deleteAction
{
NSDictionary *jsonRequest, *jsonResponse;
NGImap4Connection *connection;
SOGoMailFolder *co, *inbox;
NSURL *srcURL, *destURL;
WORequest *request;
WOResponse *response;
NSException *error;
BOOL moved, withTrash;
request = [context request];
co = [self clientObject];
srcURL = [co imap4URL];
jsonRequest = [[request contentAsString] objectFromJSONString];
withTrash = ![[jsonRequest objectForKey: @"withoutTrash"] boolValue];
moved = YES; moved = YES;
if ([co ensureTrashFolder]) if (withTrash)
{ {
connection = [co imap4Connection]; if ([co ensureTrashFolder])
srcURL = [co imap4URL];
destURL = [self _trashedURLOfFolder: srcURL withObject: co];
connection = [co imap4Connection];
inbox = [[co mailAccountFolder] inboxFolderInContext: context];
[[connection client] select: [inbox absoluteImap4Name]];
// If srcURL is a prefix of destURL, that means we are deleting
// the folder within the 'Trash' folder, as it's getting renamed
// over and over with an integer suffix (in trashedURLOfFolder:...)
// If that is the case, we simple delete the folder, instead of renaming it
if ([[destURL path] hasPrefix: [srcURL path]])
{ {
error = [connection deleteMailboxAtURL: srcURL]; connection = [co imap4Connection];
moved = NO; destURL = [self _trashedURLOfFolder: srcURL withObject: co];
connection = [co imap4Connection];
inbox = [[co mailAccountFolder] inboxFolderInContext: context];
[[connection client] select: [inbox absoluteImap4Name]];
// If srcURL is a prefix of destURL, that means we are deleting
// the folder within the 'Trash' folder, as it's getting renamed
// over and over with an integer suffix (in trashedURLOfFolder:...)
// If that is the case, we simple delete the folder, instead of renaming it
if ([[destURL path] hasPrefix: [srcURL path]])
{
error = [connection deleteMailboxAtURL: srcURL];
moved = NO;
}
else
error = [connection moveMailboxAtURL: srcURL toURL: destURL];
if (error)
{
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move/delete folder." inContext: context]
forKey: @"error"];
response = [self responseWithStatus: 500 andJSONRepresentation: jsonResponse];
}
else
{
// We unsubscribe to the old one, and subscribe back to the new one
if (moved)
[[connection client] subscribe: [destURL path]];
[self _removeFolder];
response = [self responseWith204];
}
} }
else else
error = [connection moveMailboxAtURL: srcURL toURL: destURL]; {
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move/delete folder." inContext: context]
forKey: @"message"];
response = [self responseWithStatus: 500 andJSONRepresentation: jsonResponse];
}
}
else
{
// Immediately delete mailbox
connection = [co imap4Connection];
error = [connection deleteMailboxAtURL: srcURL];
if (error) if (error)
{ {
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move/delete folder." inContext: context] jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move/delete folder." inContext: context]
@ -256,36 +320,10 @@
} }
else else
{ {
// We unsubscribe to the old one, and subscribe back to the new one [self _removeFolder];
if (moved)
[[connection client] subscribe: [destURL path]];
[[connection client] unsubscribe: [srcURL path]];
// Verify if the current folder have any collapsed threads save under it name and erase it
us = [[context activeUser] userSettings];
moduleSettings = [us objectForKey: @"Mail"];
threadsCollapsed = [moduleSettings objectForKey: @"threadsCollapsed"];
currentMailbox = [co nameInContainer];
currentAccount = [[co container] nameInContainer];
keyForMsgUIDs = [NSString stringWithFormat:@"/%@/%@", currentAccount, currentMailbox];
if (threadsCollapsed)
{
if ([threadsCollapsed objectForKey: keyForMsgUIDs])
{
[threadsCollapsed removeObjectForKey: keyForMsgUIDs];
[us synchronize];
}
}
response = [self responseWith204]; response = [self responseWith204];
} }
} }
else
{
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move/delete folder." inContext: context]
forKey: @"message"];
response = [self responseWithStatus: 500 andJSONRepresentation: jsonResponse];
}
return response; return response;
} }
@ -773,7 +811,6 @@
- (WOResponse *) _subscribeOrUnsubscribeAction: (BOOL) subscribing - (WOResponse *) _subscribeOrUnsubscribeAction: (BOOL) subscribing
{ {
NGImap4Client *client; NGImap4Client *client;
WOResponse *response;
SOGoMailFolder *co; SOGoMailFolder *co;
NSDictionary *d; NSDictionary *d;

View File

@ -620,12 +620,13 @@
* @function $delete * @function $delete
* @memberof Mailbox.prototype * @memberof Mailbox.prototype
* @desc Delete the mailbox from the server * @desc Delete the mailbox from the server
* @param {object} [options] - additional options (use {withoutTrash: true} to delete immediately)
* @returns a promise of the HTTP operation * @returns a promise of the HTTP operation
*/ */
Mailbox.prototype.$delete = function() { Mailbox.prototype.$delete = function(options) {
var _this = this; var _this = this;
return Mailbox.$$resource.remove(this.id) return Mailbox.$$resource.post(this.id, 'delete', options)
.then(function() { .then(function() {
_this.$account.$getMailboxes({reload: true}); _this.$account.$getMailboxes({reload: true});
return true; return true;
@ -674,6 +675,7 @@
* @function $deleteMessages * @function $deleteMessages
* @memberof Mailbox.prototype * @memberof Mailbox.prototype
* @desc Delete multiple messages from mailbox. * @desc Delete multiple messages from mailbox.
* @param {object} [options] - additional options (use {withoutTrash: true} to delete immediately)
* @return a promise of the HTTP operation * @return a promise of the HTTP operation
*/ */
Mailbox.prototype.$deleteMessages = function(messages, options) { Mailbox.prototype.$deleteMessages = function(messages, options) {

View File

@ -311,7 +311,7 @@
var selectedMessages = vm.selectedFolder.$selectedMessages(); var selectedMessages = vm.selectedFolder.$selectedMessages();
if (messageDialog === null && _.size(selectedMessages) > 0) if (messageDialog === null && _.size(selectedMessages) > 0)
messageDialog = Dialog.confirm(l('Warning'), messageDialog = Dialog.confirm(l('Confirmation'),
l('Are you sure you want to delete the selected messages?'), l('Are you sure you want to delete the selected messages?'),
{ ok: l('Delete') }) { ok: l('Delete') })
.then(function() { .then(function() {

View File

@ -344,14 +344,26 @@
} }
function confirmDelete(folder) { function confirmDelete(folder) {
Dialog.confirm(l('Confirmation'), l('Do you really want to move this folder into the trash ?')) Dialog.confirm(l('Warning'),
l('Do you really want to move this folder into the trash ?'),
{ ok: l('Delete') })
.then(function() { .then(function() {
folder.$delete() folder.$delete()
.then(function() { .then(function() {
$state.go('mail.account.inbox'); $state.go('mail.account.inbox');
}, function(data, status) { }, function(response) {
Dialog.alert(l('An error occured while deleting the mailbox "%{0}".', folder.name), Dialog.confirm(l('Warning'),
l(data.error)); l('The mailbox could not be moved to the trash folder. Would you like to delete it immediately?'),
{ ok: l('Delete') })
.then(function() {
folder.$delete({ withoutTrash: true })
.then(function() {
$state.go('mail.account.inbox');
}, function(response) {
Dialog.alert(l('An error occured while deleting the mailbox "%{0}".', folder.name),
l(response.error));
});
});
}); });
}); });
} }