From 800e21b05d6beef6c9151b9d7f6fedbad5e8b238 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 21 Oct 2021 17:33:39 -0400 Subject: [PATCH] feat(mail): filter messages by tags (labels) Fixes #3323 Fixes #3835 Fixes #5338 --- UI/MailerUI/English.lproj/Localizable.strings | 3 ++ UI/MailerUI/UIxMailListActions.m | 38 ++++++++++++++----- .../MailerUI/UIxMailFolderTemplate.wox | 15 ++++++++ .../js/Mailer/Mailbox.service.js | 29 ++++++++++++++ .../js/Mailer/MailboxController.js | 3 ++ 5 files changed, 79 insertions(+), 9 deletions(-) diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index c0535c391..804bb390e 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -172,6 +172,9 @@ /* Filter option in messages list */ "Show flagged messages only" = "Show flagged messages only"; +/* Aria label for icon of labels */ +"Filtered by label" = "Filtered by label"; + /* Tree */ "SentFolderName" = "Sent"; "TrashFolderName" = "Trash"; diff --git a/UI/MailerUI/UIxMailListActions.m b/UI/MailerUI/UIxMailListActions.m index 447480e1b..4e88e2ab7 100644 --- a/UI/MailerUI/UIxMailListActions.m +++ b/UI/MailerUI/UIxMailListActions.m @@ -424,29 +424,29 @@ EOQualifier *qualifier, *notDeleted, *searchQualifier; WORequest *request; NSDictionary *sortingAttributes, *content, *filter; - NSArray *filters; - NSString *searchBy, *searchInput, *searchString, *match; - NSMutableArray *qualifiers, *searchArray; + NSArray *filters, *labels; + NSString *searchBy, *searchInput, *searchString, *match, *label; + NSMutableArray *qualifiers, *searchArray, *labelQualifiers; BOOL unseenOnly, flaggedOnly; - int nbFilters, i; + int max, i; request = [context request]; content = [[request contentAsString] objectFromJSONString]; notDeleted = [EOQualifier qualifierWithQualifierFormat: @"(not (flags = %@))", @"deleted"]; - qualifier = nil; qualifiers = [NSMutableArray arrayWithObject: notDeleted]; searchString = nil; match = nil; filters = [content objectForKey: @"filters"]; + labels = [content objectForKey: @"labels"]; unseenOnly = [[content objectForKey: @"unseenOnly"] boolValue]; flaggedOnly = [[content objectForKey: @"flaggedOnly"] boolValue]; if (filters) { - nbFilters = [filters count]; - if (nbFilters > 0) { - searchArray = [NSMutableArray arrayWithCapacity: nbFilters]; - for (i = 0; i < nbFilters; i++) + max = [filters count]; + if (max > 0) { + searchArray = [NSMutableArray arrayWithCapacity: max]; + for (i = 0; i < max; i++) { filter = [filters objectAtIndex:i]; searchBy = [filter objectForKey: @"searchBy"]; @@ -489,6 +489,26 @@ searchQualifier = [EOQualifier qualifierWithQualifierFormat: @"(flags = %@)", @"flagged"]; [qualifiers addObject: searchQualifier]; } + if (labels) + { + max = [labels count]; + if (max > 0) + { + labelQualifiers = [NSMutableArray arrayWithCapacity: max]; + for (i = 0; i < max; i++) + { + label = [labels objectAtIndex: i]; + qualifier = [EOQualifier qualifierWithQualifierFormat: @"(flags = %@)", label]; + [labelQualifiers addObject: qualifier]; + } + if (max > 1) + { + qualifier = [[EOOrQualifier alloc] initWithQualifierArray: labelQualifiers]; + [qualifier autorelease]; + } + [qualifiers addObject: qualifier]; + } + } if ([qualifiers count] > 1) { diff --git a/UI/Templates/MailerUI/UIxMailFolderTemplate.wox b/UI/Templates/MailerUI/UIxMailFolderTemplate.wox index 47eaed41c..e04d473a0 100644 --- a/UI/Templates/MailerUI/UIxMailFolderTemplate.wox +++ b/UI/Templates/MailerUI/UIxMailFolderTemplate.wox @@ -93,6 +93,20 @@ sg-true-value="1" sg-false-value="0"> + + + +
+
+ {{ label.name || label.imapName }} +
+
+
@@ -302,6 +316,7 @@
+ label_outline sort diff --git a/UI/WebServerResources/js/Mailer/Mailbox.service.js b/UI/WebServerResources/js/Mailer/Mailbox.service.js index f73fc69b8..26306d5a0 100644 --- a/UI/WebServerResources/js/Mailer/Mailbox.service.js +++ b/UI/WebServerResources/js/Mailer/Mailbox.service.js @@ -400,6 +400,12 @@ if (this.$flaggedOnly) options.flaggedOnly = 1; + var labels = _.filter(_.keys(this.$filteredLabels), function (k) { + return !!_this.$filteredLabels[k]; + }); + if (labels.length) + options.labels = labels; + // Restart the refresh timer, if needed if (!Mailbox.$virtualMode) { var refreshViewCheck = Mailbox.$Preferences.defaults.SOGoRefreshViewCheck; @@ -675,6 +681,29 @@ }); }; + /** + * @function getLabels + * @memberof Mailbox.prototype + * @desc Fetch the list of labels associated to the mailbox. Use the cached value if available. + * @returns a promise of the HTTP operation + */ + Mailbox.prototype.getLabels = function() { + var _this = this; + + if (this.$labels) + return this.$labels; + + this.$filteredLabels = {}; + return Mailbox.$$resource.fetch(this.id, 'labels').then(function(data) { + _this.$labels = data; + return _this.$labels; + }); + }; + + Mailbox.prototype.filteredByLabel = function() { + return _.includes(this.$filteredLabels, 1); + }; + /** * @function $flagMessages * @memberof Mailbox.prototype diff --git a/UI/WebServerResources/js/Mailer/MailboxController.js b/UI/WebServerResources/js/Mailer/MailboxController.js index 1b483e369..7798392a0 100644 --- a/UI/WebServerResources/js/Mailer/MailboxController.js +++ b/UI/WebServerResources/js/Mailer/MailboxController.js @@ -32,6 +32,9 @@ this.messageDialog = null; // also access from Message controller this.mode = { search: false, multiple: 0 }; + if (!Mailbox.$virtualMode) + this.selectedFolder.getLabels(); // fetch labels from server + _registerHotkeys(hotkeys); // Expunge mailbox when leaving the Mail module