From f321e1c949401268024fe9a2b5cfc7901437e83e Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 3 Feb 2016 16:48:04 -0500 Subject: [PATCH] (js) Add "Move To" option for selected messages Fixes #3477 --- NEWS | 1 + UI/MailerUI/UIxMailFolderActions.m | 4 +- .../MailerUI/UIxMailFolderTemplate.wox | 68 ++++++++----- .../js/Mailer/Mailbox.service.js | 74 +++++++++----- .../js/Mailer/MailboxController.js | 96 ++++++++++--------- .../scss/components/menu/menu.scss | 24 ++++- 6 files changed, 173 insertions(+), 94 deletions(-) diff --git a/NEWS b/NEWS index 0a9256f8a..f42b04249 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Enhancements - improved scrolling behavior when deleting a single message (#3489) +- added "Move To" option for selected messages (#3477) Bug fixes - fixed blank calendar view when selecting "Descending Order" in the sort menu diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 183c3ee8b..6d230a1c2 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -478,7 +478,7 @@ response = [co moveUIDs: uids toFolder: destinationFolder inContext: context]; if (!response) { - // Verify if the message beeing delete is saved as the root of a collapsed thread + // Verify if the message being deleted is saved as the root of a collapsed thread us = [[context activeUser] userSettings]; moduleSettings = [us objectForKey: @"Mail"]; threadsCollapsed = [moduleSettings objectForKey: @"threadsCollapsed"]; @@ -501,7 +501,7 @@ else { data = [NSDictionary dictionaryWithObject: [self labelForKey: @"Error moving messages." inContext: context] - forKey: @"error"]; + forKey: @"message"]; response = [self responseWithStatus: 500 andJSONRepresentation: data]; } diff --git a/UI/Templates/MailerUI/UIxMailFolderTemplate.wox b/UI/Templates/MailerUI/UIxMailFolderTemplate.wox index 6d6d04c71..54fb94c8c 100644 --- a/UI/Templates/MailerUI/UIxMailFolderTemplate.wox +++ b/UI/Templates/MailerUI/UIxMailFolderTemplate.wox @@ -155,28 +155,6 @@ delete - - - - content_copy - - -
- - {{account.name}} - - - - - {{folder.name}} - - -
-
-
more_vert @@ -197,6 +175,52 @@ + + + + + + +
+ + {{account.name}} + + + + + {{folder.name}} + + +
+
+
+
+ + + + + + +
+ + {{account.name}} + + + + + {{folder.name}} + + +
+
+
+
diff --git a/UI/WebServerResources/js/Mailer/Mailbox.service.js b/UI/WebServerResources/js/Mailer/Mailbox.service.js index 30506f9b1..5f7c6d78f 100644 --- a/UI/WebServerResources/js/Mailer/Mailbox.service.js +++ b/UI/WebServerResources/js/Mailer/Mailbox.service.js @@ -517,6 +517,44 @@ }); }; + /** + * @function $_deleteMessages + * @memberof Mailbox.prototype + * @desc Delete multiple messages from Mailbox object. + * @param {string[]} uids - the messages uids + * @param {object[]} messages - the Message instances + * @return the index of the first deleted message + */ + Mailbox.prototype.$_deleteMessages = function(uids, messages) { + var _this = this, selectedMessages, selectedUIDs, unseen, firstIndex = this.$messages.length; + + // Decrement the unseen count + unseen = _.filter(messages, function(message, i) { return !message.isread; }); + this.unseenCount -= unseen.length; + + // Remove messages from $messages and uidsMap + _.forEachRight(this.$messages, function(message, index) { + var selectedIndex = _.findIndex(uids, function(uid) { + return message.uid == uid; + }); + if (selectedIndex > -1) { + uids.splice(selectedIndex, 1); + delete _this.uidsMap[message.uid]; + if (message.uid == _this.selectedMessage) + delete _this.selectedMessage; + _this.$messages.splice(index, 1); + if (index < firstIndex) + firstIndex = index; + } + else { + _this.uidsMap[message.uid] -= uids.length; + } + }); + + // Return the index of the first deleted message + return firstIndex; + }; + /** * @function $deleteMessages * @memberof Mailbox.prototype @@ -529,33 +567,11 @@ uids = _.pluck(messages, 'uid'); return Mailbox.$$resource.post(this.id, 'batchDelete', {uids: uids}) .then(function(data) { - var selectedMessages, selectedUIDs, unseen, firstIndex = _this.$messages.length; - // Decrement the unseenCount accordingly - unseen = _.filter(messages, function(message, i) { return !message.isread; }); - _this.unseenCount -= unseen.length; - // Remove messages from $messages and uidsMap - _.forEachRight(_this.$messages, function(message, index) { - var selectedIndex = _.findIndex(uids, function(uid) { - return message.uid == uid; - }); - if (selectedIndex > -1) { - uids.splice(selectedIndex, 1); - delete _this.uidsMap[message.uid]; - if (message.uid == _this.selectedMessage) - delete _this.selectedMessage; - _this.$messages.splice(index, 1); - if (index < firstIndex) - firstIndex = index; - } - else { - _this.uidsMap[message.uid] -= uids.length; - } - }); // Update inbox quota if (data.quotas) _this.$account.updateQuota(data.quotas); - return firstIndex; + return _this.$_deleteMessages(uids, messages); }); }; @@ -566,6 +582,8 @@ * @return a promise of the HTTP operation */ Mailbox.prototype.$copyMessages = function(uids, folder) { + var _this = this; + return Mailbox.$$resource.post(this.id, 'copyMessages', {uids: uids, folder: folder}) .then(function(data) { // Update inbox quota @@ -580,8 +598,14 @@ * @desc Move multiple messages from the current mailbox to a target one * @return a promise of the HTTP operation */ - Mailbox.prototype.$moveMessages = function(uids, folder) { - return Mailbox.$$resource.post(this.id, 'moveMessages', {uids: uids, folder: folder}); + Mailbox.prototype.$moveMessages = function(messages, folder) { + var _this = this, uids; + + uids = _.pluck(messages, 'uid'); + return Mailbox.$$resource.post(this.id, 'moveMessages', {uids: uids, folder: folder}) + .then(function() { + return _this.$_deleteMessages(uids, messages); + }); }; /** diff --git a/UI/WebServerResources/js/Mailer/MailboxController.js b/UI/WebServerResources/js/Mailer/MailboxController.js index 882c9cd1c..e24166586 100644 --- a/UI/WebServerResources/js/Mailer/MailboxController.js +++ b/UI/WebServerResources/js/Mailer/MailboxController.js @@ -24,7 +24,7 @@ vm.unselectMessages = unselectMessages; vm.confirmDeleteSelectedMessages = confirmDeleteSelectedMessages; vm.copySelectedMessages = copySelectedMessages; - // vm.moveSelectedMessages = moveSelectedMessages; + vm.moveSelectedMessages = moveSelectedMessages; vm.saveSelectedMessages = saveSelectedMessages; vm.markSelectedMessagesAsFlagged = markSelectedMessagesAsFlagged; vm.markSelectedMessagesAsUnread = markSelectedMessagesAsUnread; @@ -56,65 +56,73 @@ Dialog.confirm(l('Warning'), l('Are you sure you want to delete the selected messages?')) .then(function() { - // User confirmed the deletion - var unselectMessage = false; + var deleteSelectedMessage = false; var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { if (message.selected && message.uid == vm.selectedFolder.selectedMessage) - unselectMessage = true; + deleteSelectedMessage = true; return message.selected; }); vm.selectedFolder.$deleteMessages(selectedMessages).then(function(index) { - var nextMessage, previousMessage, nextIndex = index; - if (unselectMessage) { - if (Mailbox.$virtualMode) { - $state.go('mail.account.virtualMailbox'); - } - else { - // Select either the next or previous message - if (index > 0) { - nextIndex -= 1; - nextMessage = vm.selectedFolder.$messages[nextIndex]; - } - if (index < vm.selectedFolder.$messages.length) - previousMessage = vm.selectedFolder.$messages[index]; - if (nextMessage) { - if (nextMessage.isread && previousMessage && !previousMessage.isread) { - nextIndex = index; - nextMessage = previousMessage; - } - } - else if (previousMessage) { - nextIndex = index; - nextMessage = previousMessage; - } - if (nextMessage) { - $state.go('mail.account.mailbox.message', { messageId: nextMessage.uid }); - vm.selectedFolder.$topIndex = nextIndex; - } - else { - $state.go('mail.account.mailbox'); - } - } - } + unselectMessage(deleteSelectedMessage, index); }); }); } + function unselectMessage(message, index) { + // Unselect current message and cleverly load the next message + var nextMessage, previousMessage, nextIndex = index; + if (message) { + if (Mailbox.$virtualMode) { + $state.go('mail.account.virtualMailbox'); + } + else { + // Select either the next or previous message + if (index > 0) { + nextIndex -= 1; + nextMessage = vm.selectedFolder.$messages[nextIndex]; + } + if (index < vm.selectedFolder.$messages.length) + previousMessage = vm.selectedFolder.$messages[index]; + if (nextMessage) { + if (nextMessage.isread && previousMessage && !previousMessage.isread) { + nextIndex = index; + nextMessage = previousMessage; + } + } + else if (previousMessage) { + nextIndex = index; + nextMessage = previousMessage; + } + if (nextMessage) { + $state.go('mail.account.mailbox.message', { messageId: nextMessage.uid }); + vm.selectedFolder.$topIndex = nextIndex; + } + else { + $state.go('mail.account.mailbox'); + } + } + } + } + function copySelectedMessages(folder) { var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected; }); var selectedUIDs = _.pluck(selectedMessages, 'uid'); vm.selectedFolder.$copyMessages(selectedUIDs, '/' + folder); } - // function moveSelectedMessages(folder) { - // var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected }); - // var selectedUIDs = _.pluck(selectedMessages, 'uid'); - // vm.selectedFolder.$moveMessages(selectedUIDs, '/' + folder).then(function() { - // // TODO: refresh target mailbox? - // vm.selectedFolder.$messages = _.difference(vm.selectedFolder.$messages, selectedMessages); - // }); - // } + function moveSelectedMessages(folder) { + var moveSelectedMessage = false; + var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { + if (message.selected && + message.uid == vm.selectedFolder.selectedMessage) + moveSelectedMessage = true; + return message.selected; + }); + vm.selectedFolder.$moveMessages(selectedMessages, '/' + folder).then(function(index) { + unselectMessage(moveSelectedMessage, index); + }); + } function saveSelectedMessages() { var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected; }); diff --git a/UI/WebServerResources/scss/components/menu/menu.scss b/UI/WebServerResources/scss/components/menu/menu.scss index 6de6b9994..b39fb3f8b 100644 --- a/UI/WebServerResources/scss/components/menu/menu.scss +++ b/UI/WebServerResources/scss/components/menu/menu.scss @@ -20,4 +20,26 @@ md-sidenav { } } } -} \ No newline at end of file +} + + +// submenu hack +// See https://github.com/angular/material/issues/6096 +md-menu-content { + .md-menu { + @extend md-menu-item; + padding: 0; + > .md-button { + line-height: $menu-item-height; + &:after { + display: block; + content: '\25BC'; + position: absolute; + top: 0px; + speak: none; + transform: rotate(270deg) scaleY(0.45) scaleX(0.9); + right: 2 * $baseline-grid; + } + } + } +}