From 7a628bac129b8b981da700670f22ab379d104bfb Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 8 Nov 2016 10:26:55 -0500 Subject: [PATCH] Allow a mailbox to be deleted immediately Fixes #3875 --- UI/MailerUI/English.lproj/Localizable.strings | 4 + UI/MailerUI/UIxMailFolderActions.m | 124 +++++++++++------- UI/WebServerResources/MailerUI.js | 22 +++- 3 files changed, 103 insertions(+), 47 deletions(-) diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index 94ee8f7d2..24e1f8a2b 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -269,6 +269,10 @@ "quotasFormat" = "%{0}% used on %{1} MB"; "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 */ "Are you sure you want to delete the selected messages?" = "Are you sure you want to delete the selected messages?"; diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index f7184e72e..a48121b3b 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -170,42 +170,99 @@ return destURL; } +- (void) _removeFolder +{ + NGImap4Connection *connection; + NSMutableDictionary *moduleSettings, *threadsCollapsed;; + NSString *keyForMsgUIDs, *currentMailbox, *currentAccount; + NSURL *srcURL; + SOGoMailFolder *co; + SOGoUserSettings *us; + + 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 { - NSString *currentMailbox, *currentAccount, *keyForMsgUIDs; - NSMutableDictionary *moduleSettings, *threadsCollapsed; NGImap4Connection *connection; SOGoMailFolder *co, *inbox; NSURL *srcURL, *destURL; - SOGoUserSettings *us; WOResponse *response; NSException *error; - BOOL moved; + BOOL moved, withTrash; co = [self clientObject]; + srcURL = [co imap4URL]; + withTrash = ![[[context request] formValueForKey: @"withoutTrash"] boolValue]; moved = YES; - if ([co ensureTrashFolder]) + if (withTrash) { - connection = [co imap4Connection]; - 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]]) + if ([co ensureTrashFolder]) { - error = [connection deleteMailboxAtURL: srcURL]; - moved = NO; + connection = [co imap4Connection]; + destURL = [self _trashedURLOfFolder: srcURL withObject: co]; + 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) + { + response = [self responseWithStatus: 500]; + [response appendContentString: [self labelForKey: @"Unable to move/delete folder." inContext: context]]; + } + 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 - error = [connection moveMailboxAtURL: srcURL toURL: destURL]; + { + response = [self responseWithStatus: 500]; + [response appendContentString: [self labelForKey: @"Unable to move/delete folder." inContext: context]]; + } + } + else + { + // Immediately delete mailbox + connection = [co imap4Connection]; + error = [connection deleteMailboxAtURL: srcURL]; if (error) { response = [self responseWithStatus: 500]; @@ -213,35 +270,10 @@ } else { - // We unsubscribe to the old one, and subscribe back to the new one - 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]; - } - } + [self _removeFolder]; response = [self responseWith204]; } } - else - { - response = [self responseWithStatus: 500]; - [response appendContentString: [self labelForKey: @"Unable to move/delete folder." inContext: context]]; - } return response; } diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index ffe443803..cb4c5b7ee 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -2515,11 +2515,31 @@ function onMenuDeleteFolder(event) { showConfirmDialog(_("Confirmation"), _("Do you really want to move this folder into the trash ?"), function(event) { - triggerAjaxRequest(urlstr, folderOperationCallback, errorLabel); + triggerAjaxRequest(urlstr, deleteFolderCallback, errorLabel); disposeDialog(); }); } +function deleteFolderCallback(http) { + if (http.readyState == 4 && isHttpStatus204(http.status)) { + folderOperationCallback(http); + } + else { + var errorLabel = http.callbackData; + showConfirmDialog( + _("Warning"), + _("The mailbox could not be moved to the trash folder. Would you like to delete it immediately?"), + // Yes -- Delete immediately + function() { + var folderID = document.menuTarget.getAttribute("dataname"); + var url = URLForFolderID(folderID) + "/delete?withoutTrash=1"; + triggerAjaxRequest(url, folderOperationCallback, errorLabel); + disposeDialog(); + } + ); + } +} + function onMenuMarkFolderRead(event) { var folderID = document.menuTarget.getAttribute("dataname"); var urlstr = URLForFolderID(folderID) + "/markRead";