fix(mail): return unseen count of mailbox in msgs operations

This commit is contained in:
Francis Lachapelle
2021-06-29 17:05:48 -04:00
parent 09d300ec65
commit a35225631a
6 changed files with 98 additions and 86 deletions
+15 -12
View File
@@ -1,6 +1,6 @@
/* UIxMailFolderActions.m - this file is part of SOGo
*
* Copyright (C) 2007-2018 Inverse inc.
* Copyright (C) 2007-2021 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WORequest.h>
@@ -468,14 +469,13 @@
- (WOResponse *) batchDeleteAction
{
NSMutableDictionary *moduleSettings, *threadsCollapsed;
NSMutableDictionary *moduleSettings, *threadsCollapsed, *data;
NSString *currentMailbox, *currentAccount, *keyForMsgUIDs;
NSMutableArray *mailboxThreadsCollapsed;
SOGoMailAccount *account;
SOGoUserSettings *us;
WOResponse *response;
SOGoMailFolder *co;
NSDictionary *data;
WORequest *request;
id uids, quota;
@@ -494,18 +494,16 @@
response = (WOResponse *) [co deleteUIDs: uids useTrashFolder: &withTrash inContext: context];
if (!response)
{
data = [NSMutableDictionary dictionary];
if (!withTrash)
{
// When not using a trash folder, return the quota
account = [co mailAccountFolder];
if ((quota = [account getInboxQuota]))
{
data = [NSDictionary dictionaryWithObjectsAndKeys: quota, @"quotas", nil];
response = [self responseWithStatus: 200
andString: [data jsonRepresentation]];
[data setObject: quota
forKey: @"quotas"];
}
else
response = [self responseWithStatus: 200];
}
else
{
@@ -519,15 +517,18 @@
if (threadsCollapsed)
{
if ((mailboxThreadsCollapsed = [threadsCollapsed objectForKey:keyForMsgUIDs]))
if ((mailboxThreadsCollapsed = [threadsCollapsed objectForKey: keyForMsgUIDs]))
{
for (i = 0; i < [uids count]; i++)
[mailboxThreadsCollapsed removeObject:[uids objectAtIndex:i]];
[mailboxThreadsCollapsed removeObject: [uids objectAtIndex:i]];
[us synchronize];
}
}
response = [self responseWith204];
}
[data setObject: [NSNumber numberWithUnsignedInt: [co unseenCount]]
forKey: @"unseenCount"];
response = [self responseWithStatus: 200
andString: [data jsonRepresentation]];
}
}
else
@@ -681,7 +682,9 @@
[us synchronize];
}
}
response = [self responseWith204];
data = [NSDictionary dictionaryWithObject: [NSNumber numberWithUnsignedInt: [co unseenCount]]
forKey: @"unseenCount"];
response = [self responseWithStatus: 200 andJSONRepresentation: data];
}
else
{
+1 -1
View File
@@ -229,7 +229,6 @@
if (![subject length])
subject = @"";
// NSLog(@"*** subject = |%@|", subject);
return subject;
}
@@ -848,6 +847,7 @@
deletedUids, @"deleted",
headers, @"headers",
newSyncToken, @"syncToken",
[NSNumber numberWithUnsignedInt: [folder unseenCount]], @"unseenCount",
nil];
response = [self responseWithStatus: 200 andJSONRepresentation: data];
}
@@ -102,6 +102,61 @@
return collection;
};
/**
* @memberof Account
* @desc Refresh the unseen count for all required mailboxes.
* Starts a timer if user choose to automatically refresh folders.
* @param {array} [string] - the paths of the folders
*/
Account.refreshUnseenCount = function(folders) {
var unseenCountFolders,
fetchAllUnseenCountFolders = (Account.$Preferences.defaults.SOGoMailFetchAllUnseenCountFolders === 1),
refreshViewCheck = Account.$Preferences.defaults.SOGoRefreshViewCheck;
if (fetchAllUnseenCountFolders)
unseenCountFolders = [];
else if (folders)
unseenCountFolders = folders;
else
throw Error('SOGoMailFetchAllUnseenCountFolders is disabled and no folders list provided');
_.forEach(Account.$accounts, function(account) {
if (fetchAllUnseenCountFolders) {
// Include all mailboxes
_.forEach(account.$$flattenMailboxes, function(mailbox) {
unseenCountFolders.push(mailbox.id);
});
}
else {
// Always include the INBOX
if (!_.includes(unseenCountFolders, account.id + '/folderINBOX'))
unseenCountFolders.push(account.id + '/folderINBOX');
_.forEach(account.$$flattenMailboxes, function(mailbox) {
if (angular.isDefined(mailbox.unseenCount) &&
!_.includes(unseenCountFolders, mailbox.id))
unseenCountFolders.push(mailbox.id);
});
}
});
Account.$$resource.post('', 'unseenCount', {mailboxes: unseenCountFolders}).then(function(data) {
_.forEach(Account.$accounts, function(account) {
_.forEach(account.$$flattenMailboxes, function(mailbox) {
if (data[mailbox.id]) {
mailbox.unseenCount = data[mailbox.id];
}
});
});
});
if (refreshViewCheck && refreshViewCheck != 'manually') {
if (Account.$refreshUnseenCount)
Account.$timeout.cancel(Account.$refreshUnseenCount);
Account.$refreshUnseenCount = Account.$timeout(angular.bind(this, Account.refreshUnseenCount, folders), refreshViewCheck.timeInterval()*1000);
}
};
/**
* @function getLength
* @memberof Account.prototype
@@ -42,7 +42,6 @@
$Preferences: Preferences,
$query: { sort: 'arrival', asc: 0 }, // The default sort must match [UIxMailListActions defaultSortKey]
selectedFolder: null,
$selectedMessages: [],
$refreshTimeout: null,
$virtualMode: false,
$virtualPath: false,
@@ -167,6 +166,7 @@
this.$messages = [];
this.uidsMap = {};
this.$visibleMessages = this.$messages;
this.$selectedMessages = [];
}
angular.extend(this, data);
if (this.path) {
@@ -738,15 +738,10 @@
* @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, selectedUIDs, _$messages, unseen, firstIndex = this.$messages.length;
// Decrement the unseen count
unseen = _.filter(messages, function(message, i) { return !message.isread; });
this.unseenCount -= unseen.length;
Mailbox.prototype.$_deleteMessages = function(uids) {
var _this = this, firstIndex = this.$messages.length;
// Remove messages from $messages and uidsMap
_.forEachRight(this.$messages, function(message, index) {
@@ -767,6 +762,10 @@
}
});
if (this.threaded) {
this.updateVisibleMessages();
}
// Return the index of the first deleted message
return firstIndex;
};
@@ -787,19 +786,21 @@
// Recursive function to synchronously delete batch of messages
function _deleteMessages(start, end) {
var currentUids = uids.slice(start, end),
currentMessages = messages.slice(start, end),
data = { uids: currentUids };
if (options) angular.extend(data, options);
return Mailbox.$$resource.post(_this.id, 'batchDelete', data).then(function(data) {
if (data.unseenCount) {
_this.unseenCount = data.unseenCount;
}
if (end < uids.length) {
_this.$_deleteMessages(currentUids, currentMessages);
_this.$_deleteMessages(currentUids);
return _deleteMessages(end, Math.min(end + batchSize, uids.length));
}
else {
// Last API call; update inbox quota
if (data.quotas)
_this.$account.updateQuota(data.quotas);
return _this.$_deleteMessages(currentUids, currentMessages);
return _this.$_deleteMessages(currentUids);
}
});
}
@@ -853,9 +854,12 @@
uids = _.map(messages, 'uid');
return Mailbox.$$resource.post(this.id, 'moveMessages', {uids: uids, folder: folder})
.then(function() {
.then(function(data) {
if (data.unseenCount) {
_this.unseenCount = data.unseenCount;
}
_this.$selectedMessages = []; // reset selection
return _this.$_deleteMessages(uids, messages);
return _this.$_deleteMessages(uids);
});
};
@@ -984,17 +988,14 @@
_this.$syncToken = data.syncToken;
if (data.deleted) {
var deletedMessages = [];
_.forEachRight(data.deleted, function(uid, i) {
var j = _this.uidsMap[uid.toString()];
if (j >= 0 && _this.$messages[j])
deletedMessages.push(_this.$messages[j]);
else
if (j < 0 || !_this.$messages[j])
// Unkown message
data.deleted.splice(i, 1);
});
if (deletedMessages.length)
_this.$_deleteMessages(data.deleted, deletedMessages);
if (data.deleted.length)
_this.$_deleteMessages(data.deleted);
}
if (data.changed) {
var i = 0, j;
@@ -1013,8 +1014,14 @@
msgObject = _this.$messages[j];
_this.uidsMap[msgObject.uid] += i;
}
if (_this.threaded) {
_this.updateVisibleMessages();
}
}
}
if (data.unseenCount) {
_this.unseenCount = data.unseenCount;
}
if (data.uids) {
// Initialization phase, we received complete list of UIDs
@@ -1083,10 +1090,6 @@
});
}
if (_this.threaded) {
_this.updateVisibleMessages();
}
Mailbox.$log.debug('mailbox ' + _this.id + ' ready');
_this.$isLoading = false;
deferred.resolve(_this.$messages);
@@ -397,12 +397,6 @@
$state.go('mail.account.mailbox');
}
}
else {
$timeout(function() {
console.warn('go to mailbox');
$state.go('mail.account.mailbox');
});
}
}
this.confirmDeleteSelectedMessages = function($event) {
@@ -34,7 +34,7 @@
this.showSubscribedOnly = Preferences.defaults.SOGoMailShowSubscribedFoldersOnly;
this.refreshUnseenCount();
Account.refreshUnseenCount($window.unseenCountFolders);
_registerHotkeys(hotkeys);
@@ -270,49 +270,6 @@
}
}; // delegate
this.refreshUnseenCount = function() {
var unseenCountFolders, refreshViewCheck;
if (Preferences.defaults.SOGoMailFetchAllUnseenCountFolders === 1)
unseenCountFolders = [];
else
unseenCountFolders = $window.unseenCountFolders;
_.forEach(vm.accounts, function(account) {
if (Preferences.defaults.SOGoMailFetchAllUnseenCountFolders === 1) {
// Include all mailboxes
_.forEach(account.$$flattenMailboxes, function(mailbox) {
unseenCountFolders.push(mailbox.id);
});
}
else {
// Always include the INBOX
if (!_.includes(unseenCountFolders, account.id + '/folderINBOX'))
unseenCountFolders.push(account.id + '/folderINBOX');
_.forEach(account.$$flattenMailboxes, function(mailbox) {
if (angular.isDefined(mailbox.unseenCount) &&
!_.includes(unseenCountFolders, mailbox.id))
unseenCountFolders.push(mailbox.id);
});
}
});
Account.$$resource.post('', 'unseenCount', {mailboxes: unseenCountFolders}).then(function(data) {
_.forEach(vm.accounts, function(account) {
_.forEach(account.$$flattenMailboxes, function(mailbox) {
if (data[mailbox.id]) {
mailbox.unseenCount = data[mailbox.id];
}
});
});
});
refreshViewCheck = Preferences.defaults.SOGoRefreshViewCheck;
if (refreshViewCheck && refreshViewCheck != 'manually')
$timeout(vm.refreshUnseenCount, refreshViewCheck.timeInterval()*1000);
};
this.isDroppableFolder = function(srcFolder, dstFolder) {
return (dstFolder.id != srcFolder.id) && !dstFolder.isNoSelect();
};