diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index 15ea7e9be4..821736d3d8 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -166,6 +166,9 @@ "Mark Read" = "Mark Read"; "Untitled" = "Untitled"; +/* Filter option in messages list */ +"Show unread messages only" = "Show unread messages only"; + /* Tree */ "SentFolderName" = "Sent"; "TrashFolderName" = "Trash"; diff --git a/UI/MailerUI/UIxMailListActions.m b/UI/MailerUI/UIxMailListActions.m index 6a9e766c4c..22d44c35f1 100644 --- a/UI/MailerUI/UIxMailListActions.m +++ b/UI/MailerUI/UIxMailListActions.m @@ -421,29 +421,30 @@ - (NSString *) imap4SortOrdering - (EOQualifier *) searchQualifier { - EOQualifier *qualifier, *searchQualifier; + EOQualifier *qualifier, *notDeleted, *searchQualifier; WORequest *request; NSDictionary *sortingAttributes, *content, *filter; NSArray *filters; NSString *searchBy, *searchInput, *searchString, *match; - NSMutableArray *searchArray; + NSMutableArray *qualifiers, *searchArray; + BOOL unseenOnly; int nbFilters, 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"]; + unseenOnly = [[content objectForKey: @"unseenOnly"] boolValue]; if (filters) { nbFilters = [filters count]; if (nbFilters > 0) { searchArray = [NSMutableArray arrayWithCapacity: nbFilters]; - sortingAttributes = [content objectForKey: @"sortingAttributes"]; - if (sortingAttributes) - match = [sortingAttributes objectForKey: @"match"]; // AND, OR for (i = 0; i < nbFilters; i++) { filter = [filters objectAtIndex:i]; @@ -465,36 +466,42 @@ - (EOQualifier *) searchQualifier [self errorWithFormat: @"Missing parameters in search filter: %@", filter]; } } + sortingAttributes = [content objectForKey: @"sortingAttributes"]; + if (sortingAttributes) + match = [sortingAttributes objectForKey: @"match"]; // AND, OR if ([match isEqualToString: @"OR"]) qualifier = [[EOOrQualifier alloc] initWithQualifierArray: searchArray]; else qualifier = [[EOAndQualifier alloc] initWithQualifierArray: searchArray]; + [qualifier autorelease]; + [qualifiers addObject: qualifier]; } } - + + if (unseenOnly) + { + searchQualifier = [EOQualifier qualifierWithQualifierFormat: @"(not (flags = %@))", @"seen"]; + [qualifiers addObject: searchQualifier]; + } + + if ([qualifiers count] > 1) + { + qualifier = [[EOAndQualifier alloc] initWithQualifierArray: qualifiers]; + [qualifier autorelease]; + } + else + qualifier = notDeleted; + return qualifier; } - (NSArray *) getSortedUIDsInFolder: (SOGoMailFolder *) mailFolder { - EOQualifier *qualifier, *fetchQualifier, *notDeleted; - if (!sortedUIDs) { - notDeleted = [EOQualifier qualifierWithQualifierFormat: @"(not (flags = %@))", @"deleted"]; - qualifier = [self searchQualifier]; - if (qualifier) - { - fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers: notDeleted, qualifier, nil]; - [fetchQualifier autorelease]; - } - else - fetchQualifier = notDeleted; - - sortedUIDs = [mailFolder fetchUIDsMatchingQualifier: fetchQualifier + sortedUIDs = [mailFolder fetchUIDsMatchingQualifier: [self searchQualifier] sortOrdering: [self imap4SortOrdering] threaded: sortByThread]; - [sortedUIDs retain]; } @@ -737,6 +744,7 @@ - (NSDictionary *) getUIDsInFolder: (SOGoMailFolder *) folder * @apiParam {String} filters.searchBy Field criteria. Either subject, from, to, cc, or body. * @apiParam {String} filters.searchInput String to match. * @apiParam {String} [filters.negative] Reverse the condition when true. Defaults to false. + * @apiParam {Boolean} [unseenOnly] Filter out seen messages when true. Defaults to false. * * @apiSuccess (Success 200) {Number} threaded 1 if threading is enabled for the user. * @apiSuccess (Success 200) {Number} unseenCount Number of unread messages diff --git a/UI/Templates/MailerUI/UIxMailFolderTemplate.wox b/UI/Templates/MailerUI/UIxMailFolderTemplate.wox index 5dad98db23..324d8f9038 100644 --- a/UI/Templates/MailerUI/UIxMailFolderTemplate.wox +++ b/UI/Templates/MailerUI/UIxMailFolderTemplate.wox @@ -73,6 +73,10 @@ + + mark_as_unread + diff --git a/UI/WebServerResources/js/Mailer/Mailbox.service.js b/UI/WebServerResources/js/Mailer/Mailbox.service.js index 209a2a1ea5..6aacacd655 100644 --- a/UI/WebServerResources/js/Mailer/Mailbox.service.js +++ b/UI/WebServerResources/js/Mailer/Mailbox.service.js @@ -342,6 +342,17 @@ return angular.isDefined(this.$selectedMessage); }; + /** + * @function toggleUnseenOnly + * @memberof Mailbox.prototype + * @desc Toggle filter by unseen messages only. Requires a round trip to the server. + */ + Mailbox.prototype.toggleUnseenOnly = function() { + var _this = this; + this.$unseenOnly = !this.$unseenOnly; + this.$filter(Mailbox.$query); + }; + /** * @function $filter * @memberof Mailbox.prototype @@ -394,6 +405,9 @@ options.syncToken = this.$syncToken; } + if (this.$unseenOnly) + options.unseenOnly = 1; + // Restart the refresh timer, if needed if (!Mailbox.$virtualMode) { var refreshViewCheck = Mailbox.$Preferences.defaults.SOGoRefreshViewCheck;