Monotone-Parent: 66f9ab1d22f9d44794e9868fe8705ef4777e0012

Monotone-Revision: e16807404ac6ea20632ee7e0e21ae2db34830540

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2010-08-12T20:51:10
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2010-08-12 20:51:10 +00:00
parent 23b1304e15
commit 25fe7bbe9e
11 changed files with 157 additions and 138 deletions
+24 -1
View File
@@ -1,5 +1,28 @@
2010-08-12 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/WebServerResources/MailerUIdTree.js: (getMailboxNode): fixed
method to return unfolded nodes too.
* UI/WebServerResources/MailerUI.js: (updateUnseenCount): renamed
from "updateStatusFolders" and improved to use DOM methods.
* UI/WebServerResources/dtree.js: (Node): removed the "hasUnseen"
parameter.
* UI/MailerUI/UIxMailAccountActions.m (-listMailboxes): make use
of the "application/json" content type in the response.
* UI/MailerUI/UIxMailFolderActions.m: (-unseenCount): renamed and
moved implementation of the -[UIxMailAccountActions statusFolders]
method, splitted thereof since we now execute the method on all
mail folders.
* UI/MailerUI/UIxMailMainFrame.m (-defaultColumnsOrder): removed
accessor, made obsolete by the new propagation mechanism of user
defaults.
(-getUnseenCountForAllFolders): new accessor that returns the
value below as a string value.
* SoObjects/SOGo/SOGoDomainDefaults.m (-mailCheckAllUnseenCounts):
new method returning whether the unseen count of all mailboxes
should be checked.
@@ -15,7 +38,7 @@
memcached. In FF 3.5 and above, a bug prevents the initial cookie
from being given back to the reauthentication redirect from an
AJAX request. Therefore we open a window that will do this for us
and will close one the authentication has succeeded again.
and will close one the authentication has succeeded again.
* UI/MainUI/SOGoRootPage.m (-revoverAction): new fake action that
perform the CAS redirection and then trigger the respawn of the
-1
View File
@@ -35,7 +35,6 @@
NSString *trashFolderName;
}
- (WOResponse *) statusFoldersAction;
- (WOResponse *) listMailboxesAction;
@end
+3 -50
View File
@@ -31,8 +31,6 @@
#import <NGImap4/NGImap4Connection.h>
#import <NGImap4/NGImap4Client.h>
#import <EOControl/EOQualifier.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoDraftObject.h>
#import <Mailer/SOGoDraftsFolder.h>
@@ -124,50 +122,6 @@
return folders;
}
- (NSDictionary *) _statusFolders
{
EOQualifier *searchQualifier;
NSArray *searchResult;
NSDictionary *imapResult;
NGImap4Client *client;
NSNumber *unseen;
SOGoMailFolder *inbox;
SOGoMailAccount *co;
co = [self clientObject];
inbox = [co inboxFolderInContext: context];
client = [[inbox imap4Connection] client];
unseen = nil;
if ([client select: [inbox relativeImap4Name]])
{
searchQualifier = [EOQualifier qualifierWithQualifierFormat: @"flags = %@ AND not flags = %@", @"unseen", @"deleted"];
imapResult = [client searchWithQualifier: searchQualifier];
searchResult = [[imapResult objectForKey: @"RawResponse"] objectForKey: @"search"];
unseen = [NSNumber numberWithInt: [searchResult count]];
}
if (!unseen)
unseen = [NSNumber numberWithInt: 0];
return [NSDictionary dictionaryWithObjectsAndKeys: unseen, @"unseen", nil];
}
- (WOResponse *) statusFoldersAction
{
WOResponse *response;
NSDictionary *data;
response = [self responseWithStatus: 200];
data = [self _statusFolders];
[response setHeader: @"text/plain; charset=utf-8"
forKey: @"content-type"];
[response appendContentString: [data jsonRepresentation]];
return response;
}
- (WOResponse *) listMailboxesAction
{
SOGoMailAccount *co;
@@ -214,13 +168,12 @@
// The parameter order is important here, as if the server doesn't support
// quota, inboxQuota will be nil and it'll terminate the list of objects/keys.
data = [NSDictionary dictionaryWithObjectsAndKeys: folders, @"mailboxes",
[self _statusFolders], @"status",
inboxQuota, @"quotas",
nil];
response = [self responseWithStatus: 200];
[response setHeader: @"text/plain; charset=utf-8"
response = [self responseWithStatus: 200
andString: [data jsonRepresentation]];
[response setHeader: @"application/json"
forKey: @"content-type"];
[response appendContentString: [data jsonRepresentation]];
return response;
}
+49
View File
@@ -24,6 +24,7 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
@@ -31,6 +32,7 @@
#import <NGObjWeb/WORequest.h>
#import <NGImap4/NGImap4Connection.h>
#import <NGImap4/NGImap4Client.h>
#import <EOControl/EOQualifier.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailFolder.h>
@@ -585,4 +587,51 @@
return response;
}
- (NSDictionary *) _unseenCount
{
EOQualifier *searchQualifier;
NSArray *searchResult;
NSDictionary *imapResult;
NGImap4Connection *connection;
NGImap4Client *client;
int unseen;
SOGoMailFolder *folder;
folder = [self clientObject];
connection = [folder imap4Connection];
client = [connection client];
if ([connection selectFolder: [folder imap4URL]])
{
searchQualifier
= [EOQualifier qualifierWithQualifierFormat: @"flags = %@ AND not flags = %@",
@"unseen", @"deleted"];
imapResult = [client searchWithQualifier: searchQualifier];
searchResult = [[imapResult objectForKey: @"RawResponse"] objectForKey: @"search"];
unseen = [searchResult count];
}
else
unseen = 0;
return [NSDictionary
dictionaryWithObject: [NSNumber numberWithInt: unseen]
forKey: @"unseen"];
}
- (WOResponse *) unseenCountAction
{
WOResponse *response;
NSDictionary *data;
response = [self responseWithStatus: 200];
data = [self _unseenCount];
[response setHeader: @"text/plain; charset=utf-8"
forKey: @"content-type"];
[response appendContentString: [data jsonRepresentation]];
return response;
}
@end
+9 -6
View File
@@ -111,12 +111,6 @@
return [names jsonRepresentation];
}
- (NSString *) defaultColumnsOrder
{
return [[[self columnsDisplayOrder] objectsForKey: @"value"
notFoundMarker: @""] jsonRepresentation];
}
- (NSString *) pageFormURL
{
NSString *u;
@@ -619,5 +613,14 @@
return [self labelForKey: [currentColumn objectForKey: @"value"]];
}
- (NSString *) getUnseenCountForAllFolders
{
SOGoDomainDefaults *dd;
dd = [[context activeUser] domainDefaults];
return ([dd mailCheckAllUnseenCounts] ? @"true" : @"false");
}
@end /* UIxMailMainFrame */
+5 -5
View File
@@ -171,6 +171,11 @@
protectedBy = "ReadAcls";
pageName = "UIxMailUserRightsEditor";
};
unseenCount = {
protectedBy = "View";
actionClass = "UIxMailFolderActions";
actionName = "unseenCount";
};
saveUserRights = {
protectedBy = "Change Permissions";
pageName = "UIxMailUserRightsEditor";
@@ -383,11 +388,6 @@
actionClass = "UIxMailFolderActions";
actionName = "createFolder";
};
statusFolders = {
protectedBy = "View";
actionClass = "UIxMailAccountActions";
actionName = "statusFolders";
};
};
};
+2 -2
View File
@@ -11,9 +11,9 @@
const:userSettingsKeys="Mail"
const:jsFiles="dtree.js,MailerUIdTree.js,SOGoAutoCompletion.js,SOGoResizableTable.js,SOGoMailDataSource.js,SOGoDataTable.js">
<script type="text/javascript">
var textMailAccounts = '<var:string value="mailAccounts" const:escapeHTML="NO"/>';
var textDefaultColumnsOrder = '<var:string value="defaultColumnsOrder" const:escapeHTML="NO"/>';
var mailAccounts = <var:string value="mailAccounts" const:escapeHTML="NO"/>;
var inboxData = <var:string value="inboxData" const:escapeHTML="NO"/>;
var getUnseenCountForAllFolders = <var:string value="getUnseenCountForAllFolders"/>;
</script>
<style type="text/css">
<var:if condition="horizontalDragHandleStyle">
+57 -58
View File
@@ -3,18 +3,12 @@
/* JavaScript for SOGoMail */
var accounts = [];
var mailboxTree;
var mailAccounts;
if (typeof textMailAccounts != 'undefined') {
if (textMailAccounts.length > 0)
mailAccounts = textMailAccounts.evalJSON(true);
else
mailAccounts = new Array();
}
var Mailer = {
currentMailbox: null,
currentMailboxType: "",
currentMessages: {},
unseenCountMailboxes: [],
maxCachedMessages: 20,
cachedMessages: new Array(),
foldersStateTimer: false,
@@ -164,11 +158,9 @@ function markMailInWindow(win, msguid, markread) {
}
if (unseenCount != 0) {
if (Mailer.currentMailboxType == "inbox") {
var node = mailboxTree.getMailboxNode(Mailer.currentMailbox);
if (node) {
updateStatusFolders(node, unseenCount, true);
}
var node = mailboxTree.getMailboxNode(Mailer.currentMailbox);
if (node) {
updateUnseenCount(node, unseenCount, true);
}
}
}
@@ -362,11 +354,9 @@ function deleteSelectedMessages(sender) {
messageList.deselectAll();
updateMessageListCounter(0 - rows.length, true);
if (unseenCount < 0) {
if (Mailer.currentMailboxType == "inbox") {
var node = mailboxTree.getMailboxNode(Mailer.currentMailbox);
if (node) {
updateStatusFolders(node, unseenCount, true);
}
var node = mailboxTree.getMailboxNode(Mailer.currentMailbox);
if (node) {
updateUnseenCount(node, unseenCount, true);
}
}
var url = ApplicationBaseURL + encodeURI(Mailer.currentMailbox) + "/batchDelete";
@@ -676,6 +666,7 @@ function openMailbox(mailbox, reload) {
else
dataSource.load(urlParams);
Mailer.dataSources.set(key, dataSource);
getUnseenCountForFolder(mailbox);
}
Mailer.dataTable.setSource(dataSource);
messageList.deselectAll();
@@ -683,6 +674,10 @@ function openMailbox(mailbox, reload) {
configureDraggables();
Mailer.currentMailbox = mailbox;
if (!getUnseenCountForAllFolders && Mailer.unseenCountMailboxes.indexOf(mailbox) == -1) {
Mailer.unseenCountMailboxes.push(mailbox);
}
// Restore previous selection
var currentMessage = Mailer.currentMessages[mailbox];
if (currentMessage) {
@@ -740,33 +735,36 @@ function messageListCallback(row, data, isNew) {
}
}
function getStatusFolders() {
var account = Mailer.currentMailbox.split("/")[1];
var url = ApplicationBaseURL + encodeURI(account) + '/statusFolders';
if (document.statusFoldersAjaxRequest) {
document.statusFoldersAjaxRequest.aborted = true;
document.statusFoldersAjaxRequest.abort();
}
document.statusFoldersAjaxRequest = triggerAjaxRequest(url,
statusFoldersCallback,
Mailer.currentMailbox);
}
function statusFoldersCallback(http) {
var div = $('mailboxContent');
var table = $('messageList');
if (http.status == 200) {
document.statusFoldersAjaxRequest = null;
var data = http.responseText.evalJSON(true);
var node = mailboxTree.getMailboxNode(http.callbackData);
function refreshUnseenCounts() {
for (var i = 0; i < Mailer.unseenCountMailboxes.length; i++) {
var mailboxPath = Mailer.unseenCountMailboxes[i];
var node = mailboxTree.getMailboxNode(mailboxPath);
if (node) {
updateStatusFolders(node, data.unseen, false);
getUnseenCountForFolder(mailboxPath);
}
}
}
function updateStatusFolders(node, count, isDelta) {
function getUnseenCountForFolder(mailbox) {
var url = ApplicationBaseURL + encodeURI(mailbox) + '/unseenCount';
triggerAjaxRequest(url, unseenCountCallback, mailbox);
}
function unseenCountCallback(http) {
var div = $('mailboxContent');
var table = $('messageList');
if (http.status == 200) {
document.unseenCountAjaxRequest = null;
var data = http.responseText.evalJSON(true);
var node = mailboxTree.getMailboxNode(http.callbackData);
if (node) {
updateUnseenCount(node, data.unseen, false);
}
}
}
function updateUnseenCount(node, count, isDelta) {
var unseenSpan = null;
var counterSpan = null;
@@ -775,7 +773,6 @@ function updateStatusFolders(node, count, isDelta) {
counterSpan = spans[0];
unseenSpan = counterSpan.parentNode;
}
if (counterSpan) {
if (typeof(count) == "undefined" || isDelta) {
if (typeof(count) == "undefined") {
@@ -788,18 +785,25 @@ function updateStatusFolders(node, count, isDelta) {
content += cNode.nodeValue;
}
}
count += parseInt(content.replace(/[()]/, "", "g"));
var digits = "";
for (var i = 0; i < content.length; i++) {
var code = content.charCodeAt(i);
if (code > 47 && code < 58) {
digits += content[i];
}
}
count += parseInt(digits);
}
while (counterSpan.firstChild) {
counterSpan.removeChild(counterSpan.firstChild);
}
counterSpan.appendChild(document.createTextNode(" (" + count + ")"));
if (count > 0) {
counterSpan.setStyle({ display: "inline" });
counterSpan.removeClassName("hidden");
unseenSpan.addClassName("unseen");
}
else {
counterSpan.setStyle({ display: "none" });
counterSpan.addClassName("hidden");
unseenSpan.removeClassName("unseen");
}
}
@@ -1689,18 +1693,6 @@ function initMailer(event) {
sorting["ascending"] = false;
}
// Define columns order
if (typeof UserDefaults["SOGoMailListViewColumnsOrder"] == "undefined") {
var defaultColumnsOrder;
if (typeof textDefaultColumnsOrder != 'undefined') {
if (textDefaultColumnsOrder.length > 0)
defaultColumnsOrder = textDefaultColumnsOrder.evalJSON(true);
else
defaultColumnsOrder = new Array();
}
UserDefaults["SOGoMailListViewColumnsOrder"] = defaultColumnsOrder;
}
if (!$(document.body).hasClassName("popup")) {
//initDnd();
@@ -1759,6 +1751,7 @@ function initMessageCheckTimer() {
function onMessageCheckCallback(event) {
refreshMailbox();
refreshUnseenCounts();
}
function initMailboxTree() {
@@ -1796,10 +1789,16 @@ function initMailboxTree() {
function initMailboxTreeCB() {
updateMailboxTreeInPage();
updateMailboxMenus();
getStatusFolders();
checkAjaxRequestsState();
getFoldersState();
configureDroppables();
if (getUnseenCountForAllFolders) {
for (var i = 0; i < mailboxTree.aNodes.length; i++) {
var mailboxPath = mailboxTree.aNodes[i].dataname;
Mailer.unseenCountMailboxes.push(mailboxPath);
}
refreshUnseenCounts();
}
}
function onLoadMailboxesCallback(http) {
@@ -1811,8 +1810,9 @@ function onLoadMailboxesCallback(http) {
accounts[accountIdx] = newAccount;
mailboxTree.addMailAccount(newAccount);
}
else
else {
log ("onLoadMailboxesCallback " + http.status);
}
}
}
@@ -2517,7 +2517,6 @@ Mailbox.prototype = {
}
};
function configureDraggables () {
var mainElement = $("dragDropVisual");
Draggables.empty ();
+4 -8
View File
@@ -16,15 +16,11 @@ var MailerUIdTreeExtension = {
else
icon = "";
var displayName = this.folderNames[type];
var hasUnseen = false;
if (!displayName)
displayName = name;
if (typeof unseen != "undefined") {
hasUnseen = true;
displayName += " <span class=\"unseenCount\">(" + parseInt(unseen) + ")</span>";
}
displayName += "<span class=\"unseenCount hidden\"> (" + parseInt(unseen) + ")</span>";
this.add(this.elementCounter, parent, displayName, 1, '#', fullName,
type, '', '', icon, icon, hasUnseen);
type, '', '', icon, icon, true);
this.elementCounter++;
},
_addFolder: function (parent, folder) {
@@ -61,10 +57,10 @@ var MailerUIdTreeExtension = {
},
getMailboxNode: function(mailbox) {
var childNode = null;
for (var i = 0; !childNode && i < this.aNodes.length; i++) {
for (var i = 0; (childNode == null) && (i < this.aNodes.length); i++) {
var aNode = this.aNodes[i];
if (aNode.dataname == mailbox) {
childNode = $("tgmailboxTree" + aNode.id);
childNode = $("smailboxTree" + aNode.id);
}
}
+3 -6
View File
@@ -21,7 +21,7 @@ function dTreeQuote(str) {
// Node object
function Node(id, pid, name, isParent, url, dataname, datatype, title, target,
icon, iconOpen, open, hasUnseen) {
icon, iconOpen, open) {
this.isParent = isParent;
this.id = id;
this.pid = pid;
@@ -33,7 +33,6 @@ function Node(id, pid, name, isParent, url, dataname, datatype, title, target,
this.iconOpen = iconOpen;
this.dataname = dataname;
this.datatype = datatype;
this.hasUnseen = hasUnseen;
this._io = open || false;
this._is = false;
this._ls = false;
@@ -90,10 +89,10 @@ dTree.prototype = {
// Adds a new node to the node array
add: function(id, pid, name, isParent, url, datatype,
title, target, icon, iconOpen, open, hasUnseen) {
title, target, icon, iconOpen, open) {
this.aNodes[this.aNodes.length] = new Node(id, pid, name, isParent, url,
datatype, title, target, icon,
iconOpen, open, false, hasUnseen);
iconOpen, open, false);
},
preload: function () {
@@ -199,8 +198,6 @@ dTree.prototype = {
var span = this.objects['namespan'].cloneNode (true);
if (!node.isParent)
span.addClassName ("leaf");
if (node.hasUnseen)
span.addClassName ("unseen");
span.update (node.name);
link.appendChild (img);
+1 -1
View File
@@ -483,7 +483,7 @@ LI[class~="_selected"].denied
background-color: #f33;
}
DIV.hidden
.hidden
{ visibility: hidden; }
/* folder tree (js) )*/