diff --git a/extensions/webmail/static/css/webmail.css b/extensions/webmail/static/css/webmail.css
index 7c9a7c60c..1e988e462 100644
--- a/extensions/webmail/static/css/webmail.css
+++ b/extensions/webmail/static/css/webmail.css
@@ -1,114 +1,128 @@
-#listing {
- position: absolute;
- left: 160px;
- right: 0px;
- top: 130px;
- height: expression(document.body.clientHeight - 35 + "px");
+body, html {
+ overflow: hidden;
+ height: 100%;
+}
+
+#leftcol {
+ /*position: fixed;
+ top: 60px;
+ left: 0;
+ width: 200px;
+ padding-left: 15px;
+ overflow: hidden;*/
+}
+
+#folders {
+ position: fixed;
+ top: 60px;
+ left: 15px;
+ width: 200px;
+ overflow-y: auto;
+ margin-bottom: 5px;
+}
+
+#mboxes_container {
overflow: auto;
}
-html > body #listing {
+#menubar {
position: fixed;
- bottom: 35px;
+ left: 215px;
+ padding-left: 15px;
}
-body.loading {
- display: block;
- filter: alpha(opacity=50);
- opacity: 0.5;
- z-index: 3;
- background: #FFF url("../../css/spinner.gif") center center no-repeat;
+#listing {
+ position: fixed;
+ left: 215px;
+ right: 0;
+ padding-left: 15px;
}
-.clearfix:after {
- content: ".";
- display: block;
- clear: both;
- visibility: hidden;
- overflow: hidden;
- line-height: 0;
- height: 0;
-}
-
-.clearfix {
- display: inline-block;
-}
-
-html[xmlns] .clearfix {
- display: block;
-}
-
-* html .clearfix {
- height: 1%;
- overflow: visible;
-}
-
-/*thead tr {
- position: relative;
- top: expression(offsetParent.scrollTop);
- z-index: 1;
- padding: 0;
-}*/
-
-/*table#emails > tbody {
- position: fixed;
- bottom: 35px;
- top: 155px;
- left: 155px;
- right: 0px;
- overflow-x: hidden;
- overflow-y: auto;
-}*/
-
-#emails th {
- /*position: relative;*/
-}
-
-#emails th input {
- margin: 0;
-}
-
-#emails tr {
- width: 100%;
- border-bottom: 1px solid #C8D6E8;
- user-select: none; /* CSS3 */
- -moz-user-select: none; /* Gecko (Firefox) */
- -khtml-user-select: none; /* Webkit (Safari, Chrome) */
-}
-
-.draggable {
- cursor: move;
- /*position: relative;*/
+#mailcontent {
border: 0;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
}
-.draggable img {
- position: static;
+.unseen {
+ font-weight: bold;
}
-ul.hidden {
- display: none;
+td[name="date"] {
+ text-align: right;
}
-ul.visible {
- display: block;
- padding-bottom: 0;
+#quotabar {
+ margin: 12px 0 0 15px;
+ width: 200px;
}
-/* Compose mail page */
-#compose-container {
+#quotaraw {
+ margin-left: 10px;
+}
+
+/*
+ * Mailboxes list
+ */
+#mboxactions {
+ position: fixed;
+ padding-left: 14px;
+}
+
+#mboxactions .btn-toolbar {
+ margin-bottom: 0px;
+}
+
+#folders li {
+ position: relative;
+}
+
+div.clickbox {
position: absolute;
left: 0px;
- right: 10px;
- top: 0;
- bottom: 0;
+ top: 2px;
+ width: 14px;
+ height: 14px;
+}
+
+div.collapsed {
+ background-image: url("/static/pics/collapsed.png");
+ background-repeat: no-repeat;
+}
+
+div.expanded {
+ background-image: url("/static/pics/expanded.png");
+ background-repeat: no-repeat;
+}
+
+/*
+ * Compose form
+ */
+#mailheader {
+ position: relative;
+ padding-bottom: 5px;
+}
+
+#mailheader input {
+ width: 99%;
+ padding: 2px 0;
+}
+
+#mailheader textarea {
+ width: 99%;
+ height: 40px;
+ padding: 2px 0;
+}
+
+#mailheader label {
+ text-align: left;
}
#attachments {
position: relative;
- border: 1px solid #cccccc;
- background-color: #eee;
- margin: 10px 0 5px 0;
+ margin: 1px 0 5px 0;
padding: 5px 0;
cursor: pointer;
width: 100%;
@@ -121,133 +135,65 @@ ul.visible {
#list {
position: absolute;
top: 5px;
- left: 130px;
+ left: 160px;
font-weight: bold;
}
+#body_container {
+ position: absolute;
+ left: 15px;
+ right: 0px;
+ bottom: 15px;
+}
+
+#id_body {
+ width: 99%;
+ height: 100%;
+}
+
+/*
+ * Attachments form
+ */
+#submit {
+ margin: 0 auto;
+}
+
+#attachment_list {
+ margin-top: 20px;
+ height: 150px;
+ overflow-x: hidden;
+ overflow-y: auto;
+ padding: 2px;
+}
+
+#attachment_list i,
+#attachment_list label {
+ float: left;
+}
+
.shortlist {
font-weight: normal !important;
font-style: italic;
}
-div.row {
- width: 100%;
- margin: 5px 0;
-}
-
-div.row label {
- width: 120px;
- font-size: small;
- padding: 3px 0;
-}
-
-div.input_container {
- position: static;
- margin-left: 130px;
-}
-
-textarea {
- border: 1px solid #cccccc;
- background-color: #eee;
- width: 100%;
- height: 40px;
- word-wrap: break-word;
- resize: none;
- padding: 2px 0;
-}
-
-textarea:hover {
- background-color: #ffffcc;
-}
-
-#body_container {
- position: absolute;
- top: 205px;
- left: 0;
- right: 0px;
- bottom: 15px;
-}
-
-#id_body {
- background: white;
- width: 100%;
- height: 100%;
-}
-
-#mailheader input {
- width: 100%;
- padding: 2px 0;
-}
-
-#mailheader {
- position: relative;
- padding-bottom: 5px;
-}
-
-/* Progress bar */
-#quotalabel {
- float: left;
- padding: 7px 2px 0 5px;
- display: none;
-}
-
-#quotabox {
- display: none;
- float: left;
- margin: 5px;
- width: 300px;
- padding: 0;
-}
-
-#box {
- /*border: 1px solid #ccc; */
- width: 200px;
- background: url(../../pics/progressbar_bg.gif) right center no-repeat;
- height: 19px;
- float: left;
-}
-
-#perc {
- background: url(../../pics/progressbar.gif) right center no-repeat;
- height: 19px;
-}
-
-#quotatext {
- padding: 2px 0 0 2px;
- float: left;
-}
-
-#fdmenu { border:1px solid #999; padding:0; background:#eee; width:150px; display:none; }
-#fdmenu .separator { border-top:1px solid #999; }
-#fdmenu ul { list-style-type:none; margin:0; padding:0; }
-#fdmenu li { margin:0; padding:0; }
-#fdmenu li a { display:block; padding:5px 10px 5px 5px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; }
-#fdmenu li a:hover { background-color:#ddd; }
-#fdmenu img { float:left; margin: 0 5px 0 0; }
-
-.folder_menu {
- float: right;
- opacity: 0.8;
-}
-
-.folder_btn {
- float: right;
- margin: 3px;
-}
-
-.folder_menubar {
- clear: both;
-}
-
+/*
+ * Drap & Drop
+ */
.dragbox {
- position : absolute;
- opacity : 0.8;
- width : 200px;
padding : 5px;
text-align : center;
- height : 25px;
- border : 1px solid #333;
background : white;
- display: none;
z-index : 3;
+}
+
+/*
+ * Folder form
+ */
+.modal-body {
+ max-height: 300px;
+ overflow-y: auto;
+}
+
+#folders2 li {
+ position: relative;
}
\ No newline at end of file
diff --git a/extensions/webmail/static/js/fdmenu.js b/extensions/webmail/static/js/fdmenu.js
deleted file mode 100644
index 570d6e80d..000000000
--- a/extensions/webmail/static/js/fdmenu.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Simple dropdown menu plugin used for folders manipulation.
- *
- */
-var FdMenu = new Class({
- Implements: [Options],
-
- options: {
- modify_url: "",
- delete_url: ""
- },
-
- add_entry: function(name, label, pic, url, onclick) {
- var item = new Element("li");
- var picpath = static_url("pics/" + pic);
-
- this[name] = new Element("a")
- .set("html", "
" + label)
- .addEvent("click", onclick.bind(this))
- .inject(item);
- item.inject(this.list);
- },
-
- initialize: function(options) {
- this.setOptions(options);
-
- this.container = new Element("div", {"id" : "fdmenu"})
- .addClass("fdmenu");
- this.list = new Element("ul");
-
- this.add_entry("modbutton", gettext("Edit folder"),
- "edit.png", this.options.modify_url, function(evt) {
- evt.stop();
- SqueezeBox.open(evt.target.get("href"), {
- handler: "iframe",
- size: {x: 350, y: 400},
- closeBtn: true
- });
- $(document.body).fireEvent("click");
- });
-
- this.add_entry("delbutton", gettext("Delete folder"), "remove.png",
- this.options.delete_url, function(evt) {
- evt.stop();
- $(document.body).fireEvent("click");
- if (!confirm(gettext("Delete folder?"))) {
- return;
- }
- new Request.JSON.mdb({
- url: evt.target.get("href"),
- method: "GET",
- onSuccess: function(resp) {
- if (resp.status == "ok") {
- var dfolder = this.current_folder + "/";
-
- if (dfolder == current_anchor.base) {
- var pfolder = ((this.current_folder.split(".")).slice(0, -1)).join(".");
- if (pfolder == "") {
- pfolder = "INBOX";
- }
- current_anchor.baseurl(pfolder, 1);
- }
- current_anchor.loading_message = gettext("Folder deleted");
- current_anchor.loading_color = "green";
- current_anchor.update(1);
- } else {
- infobox.error(resp.error);
- infobox.hide(2);
- }
- }.bind(this)
- }).send();
- }
- );
- this.list.inject(this.container);
- this.shown = false;
-
- $(document.body).addEvent("click", function() {
- if (this.shown) {
- this.hide();
- }
- }.bind(this));
- },
-
- show: function(origin, folder) {
- var position = origin.getPosition();
-
- this.container.setStyles({
- position: "absolute",
- top: position.y + 5,
- left: position.x + 5,
- display: "block"
- });
- this.container.inject(document.body);
- this.shown = true;
- this.current_folder = folder;
- this.modbutton.set("href", this.options.modify_url + "?name=" + folder);
- this.delbutton.set("href", this.options.delete_url + "?name=" + folder);
- },
-
- hide: function() {
- this.container.setStyles({
- display: "none"
- });
- this.container = this.container.dispose();
- this.shown = false;
- },
-
- toggle: function(origin, folder) {
- return (!this.shown) ? this.show(origin, folder) : this.hide();
- }
-});
\ No newline at end of file
diff --git a/extensions/webmail/static/js/webmail.js b/extensions/webmail/static/js/webmail.js
index 6ec536852..622cf2b98 100644
--- a/extensions/webmail/static/js/webmail.js
+++ b/extensions/webmail/static/js/webmail.js
@@ -1,533 +1,589 @@
-var Webmail = new Class({
- Implements: [Options],
+/*
+ * The javascript code that brings the webmail to life!
+ */
+var Webmail = function(options) {
+ this.initialize(options);
+};
+
+Webmail.prototype = {
+ constructor: Webmail,
- /*
- * Default values for options
- */
defaults: {
- refreshRate: 0,
- modify_url: "",
- delete_url: "",
+ poller_interval: 300, /* in seconds */
+ poller_url: "",
move_url: "",
- submboxes_url: ""
+ submboxes_url: "",
+ delattachment_url: "",
+ deflocation: "",
+ defcallback: "",
+ ro_mboxes: ["INBOX"]
},
- /*
- * Constructor
- */
initialize: function(options) {
- this.setOptions(options);
-
+ this.options = $.extend({}, this.defaults, options);
this.rtimer = null;
this.editorid = "id_body";
- this.init_folders_buttons();
- this.init_folders_browsing();
- this.init_quota_bar();
-
- /* FIXME: à faire uniquement pour le mode pushState */
- /*this.init_emails_table();*/
-
- current_anchor.disable_spinner();
- current_anchor.register_callback("listmailbox",
- this.listmailbox_callback.bind(this));
- current_anchor.register_callback("viewmail", this.viewmail_callback.bind(this));
- current_anchor.register_callback("compose", this.compose_callback.bind(this));
- current_anchor.register_callback("reply", this.compose_callback.bind(this));
- current_anchor.register_callback("replyall", this.compose_callback.bind(this));
- current_anchor.register_callback("forward", this.compose_callback.bind(this));
- current_anchor.register_callback("delete", this.delete_callback);
-
- this.gspinner = new Spinner("document.body", {
- message: gettext("Loading, please wait..."),
- 'class': "spinner-noop"
+ this.navobject = new History({
+ deflocation: this.options.deflocation,
+ defcallback: this.options.defcallback
});
- this.gspinner.addEvent("hide", function(target) {
- this.gspinner.destroy();
- delete(this.gspinner);
- current_anchor.enable_spinner();
- }.bind(this));
- this.gspinner.show();
+ this.poller = new Poller(this.options.poller_url, {
+ interval: this.options.poller_interval * 1000,
+ success_cb: $.proxy(this.poller_cb, this),
+ args: this.get_visible_mailboxes
+ });
+ this.record_unseen_messages();
+
+ $("#folders").css({
+ bottom: $("#bottom-bar").outerHeight(true)
+ });
+ $("#mboxactions").css({
+ bottom: $("#bottom-bar").outerHeight(true) + 10
+ });
+ this.resize();
+
+ this.init_droppables();
+ this.register_navcallbacks();
+ this.listen();
},
- send_mark_request: function(evt) {
- evt.stop();
- if (!this.emails_table._selectedRows.length) {
- return;
- }
- var ids = new Array();
+ register_navcallbacks: function() {
+ this.navobject.register_callback("listmailbox",
+ $.proxy(this.listmailbox_callback, this));
+ this.navobject.register_callback("compose",
+ $.proxy(this.compose_callback, this));
+ this.navobject.register_callback("viewmail",
+ $.proxy(this.viewmail_callback, this));
- this.emails_table._selectedRows.each(function(item, index) {
- ids.include(item.get("id"));
- });
- this.simple_request(evt.target.get("href"), {
- ids : ids.join()
- }, function(response) {
- if (response.action == "read") {
- this.emails_table._selectedRows.removeClass("unseen");
- } else {
- this.emails_table._selectedRows.addClass("unseen");
- }
- /*
- * MAJ de l'affichage du nombre de messages non lus
- * (faire fonction à part)
- */
- }.bind(this));
+ this.navobject.register_callback("reply",
+ $.proxy(this.compose_callback, this));
+ this.navobject.register_callback("replyall",
+ $.proxy(this.compose_callback, this));
+ this.navobject.register_callback("forward",
+ $.proxy(this.compose_callback, this));
+ this.navobject.register_callback("delete",
+ $.proxy(this.delete_callback, this));
+ },
+
+ listen: function() {
+ $(window).resize(this.resize);
+
+ $(document).on("click", "a[name=compose]",
+ $.proxy(this.compose_loader, this));
+ $(document).on("click", "a[name*=mark-]",
+ $.proxy(this.send_mark_request, this));
+ $(document).on("click", "a[name=empty]",
+ $.proxy(this.empty, this));
+ $(document).on("click", "#bottom-bar a",
+ $.proxy(this.getpage_loader, this));
+
+ $(document).on("click", "a[name=loadfolder]",
+ $.proxy(this.listmailbox_loader, this));
+ $(document).on("click", "a[name=selectfolder]",
+ this.select_parent_mailbox),
+ $(document).on("click", "div[class*=clickbox]",
+ $.proxy(this.mbox_state_callback, this));
+ $(document).on("click", "a[name=editmbox]",
+ $.proxy(this.edit_mbox, this));
+ $(document).on("click", "a[name=removembox]",
+ $.proxy(this.remove_mbox, this));
+
+ $(document).on("dblclick", "tbody>tr",
+ $.proxy(this.viewmail_loader, this));
+
+ $(document).on("click", "a[name=reply]",
+ $.proxy(this.reply_loader, this));
+ $(document).on("click", "a[name=replyall]",
+ $.proxy(this.reply_loader, this));
+ $(document).on("click", "a[name=forward]",
+ $.proxy(this.reply_loader, this));
+ $(document).on("click", "a[name=delete]",
+ $.proxy(this.delete_message, this));
+ $(document).on("click", "a[name=activate_links]",
+ $.proxy(function(e) { this.display_mode(e, "1"); }, this));
+ $(document).on("click", "a[name=disable_links]",
+ $.proxy(function(e) { this.disable_mode(e, "0"); }, this));
+
+ $(document).on("click", "a[name=sendmail]",
+ $.proxy(this.sendmail, this));
+
+ $(document).on("click", "#attachments", $.proxy(function(e) {
+ var $div = $(e.target).parent();
+ modalbox(e, undefined, $div.attr("name"),
+ $.proxy(this.attachments_init, this));
+ }, this));
+ },
+
+ record_unseen_messages: function() {
+ var unseen_counters = {};
+
+ $("#folders").find("a.unseen").each(function() {
+ var $this = $(this);
+ unseen_counters[$this.attr("href")] = parseInt($this.attr("data-toggle"));
+ });
+ this.unseen_counters = unseen_counters;
+ },
+
+ resize: function() {
+ $("#mboxes_container").height($("#folders").height() - $("#mboxactions").height());
},
/*
- * Open/Close the menu containing folder buttons
+ * Simple helper to retrieve the currently selected mailbox.
*/
- toggle_folder_buttons: function(evt) {
- var parent = evt.target.getParent();
- var fdname = parent.getFirst("a[name=loadfolder]").get("href");
-
- this.fdmenu.toggle(evt.target, fdname);
- evt.stop();
+ get_current_mailbox: function() {
+ if (this.navobject.params.action != "listmailbox") {
+ return null;
+ }
+ return (this.navobject.params.name)
+ ? this.navobject.params.name : "INBOX";
},
/*
- * Initializes the misc. buttons available to manipulate folders.
+ * Enable or disable edit and remove actions for the currently
+ * selected mailbox.
*/
- init_folders_buttons: function() {
- $$("li[class*=clickable]").removeEvents();
-
- $$("a[name=loadfolder]").addEvent("click", this.listmailbox_loader.bind(this));
-
- SqueezeBox.assign($("folders").getElements('a[class=boxed]'), {
- parse: 'rel'
- });
-
- this.fdmenu = new FdMenu({
- modify_url: this.options.modify_url,
- delete_url: this.options.delete_url
- });
-
- $$("img[class*=footer]")
- .addEvent("click", this.toggle_folder_buttons.bind(this));
- },
-
- /*
- * Open/Close a mailbox with children
- */
- toggle_mbox_state: function(div, ul) {
- if (ul.hasClass("hidden")) {
- div.removeClass("collapsed").addClass("expanded");
- ul.removeClass("hidden").addClass("visible");
+ enable_mb_actions: function(state) {
+ if (state === undefined) {
+ state = true;
+ }
+ if (state) {
+ $("a[name=editmbox], a[name=removembox]").removeClass("disabled");
} else {
- div.removeClass("expanded").addClass("collapsed");
- ul.removeClass("visible").addClass("hidden");
+ $("a[name=editmbox], a[name=removembox]").addClass("disabled");
+ }
+ },
+
+ page_update: function(response) {
+ /*if (this.gspinner) {
+ this.gspinner.hide();
+ }*/
+ if (response.menu != undefined) {
+ $("#menubar").html(response.menu);
+ $("#searchfield").searchbar({navobj: this.navobject});
+ }
+ if (response.navbar) {
+ $("#bottom-bar-right").html(response.navbar);
+ }
+ $("#listing").html(response.listing);
+ $("#listing").css({
+ top: $("#menubar").outerHeight(true) + 60 + "px",
+ bottom: $("#bottom-bar").outerHeight(true) + "px",
+ overflow: "auto"
+ });
+ },
+
+ /*
+ * Set the *unseen messages* counter for a particular mailbox in
+ * the list. If the mailbox is currently selected, we update the
+ * listing.
+ */
+ set_unseen_messages: function(mailbox, value) {
+ if (this.poller.running_request) {
+ return;
+ }
+ if (this.unseen_counters[mailbox] != undefined
+ && value == this.unseen_counters[mailbox]) {
+ return;
+ }
+
+ if (this.navobject.params.action == "listmailbox") {
+ var curmb = this.get_current_mailbox();
+ if (curmb == mailbox) {
+ this.navobject.update(true);
+ }
+ }
+
+ var $link = $('a[href="' + mailbox + '"]');
+ var parts = mailbox.split('.');
+ var dname = " " + parts[parts.length - 1];
+ var $i = $link.children("i");
+
+ this.unseen_counters[mailbox] = value;
+ if (value) {
+ $link.html(dname + " (" + value + ")");
+ $link.addClass("unseen");
+ } else {
+ $link.html(dname);
+ $link.removeClass("unseen");
+ }
+ $link.prepend($i);
+ },
+
+ /*
+ * Increment or decrement the *unseen messages* counter of the
+ * given mailbox.
+ */
+ change_unseen_messages: function(mailbox, offset) {
+ if (this.unseen_counters[mailbox] === undefined) {
+ this.unseen_counters[mailbox] = 0;
+ }
+ this.set_unseen_messages(mailbox, this.unseen_counters[mailbox] + offset);
+ },
+
+ /*
+ * Returns a list containing the currently visible mailboxes (in
+ * the left tree).
+ */
+ get_visible_mailboxes: function() {
+ var res = new Array();
+
+ $("#folders").find("ul:visible").children("li.droppable").each(function() {
+ res.push($(this).attr("name"));
+ });
+ return "mboxes=" + res.join(",");
+ },
+
+ /*
+ * Sends a refresh request to the server. This method is called
+ * periodically to check for new messages. (not really optimized)
+ */
+ update_unseen_messages: function(mailbox) {
+ $.ajax({
+ url: this.options.poller_url + "?selection=" + mailbox,
+ dataType: 'json',
+ success: $.proxy(this.poller_cb, this)
+ });
+ },
+
+ /*
+ * Poller callback.
+ */
+ poller_cb: function(data) {
+ for (var mb in data.counters) {
+ this.set_unseen_messages(mb, parseInt(data.counters[mb]));
}
},
/*
* Inject new mailboxes under a given parent in the tree.
*/
- inject_mailboxes: function(parent, mboxes) {
- var ul = new Element("ul", {
- name: parent.get("name"),
- 'class': "hidden"
- }).inject(parent);
+ inject_mailboxes: function($parent, mboxes) {
+ var $ul = $("
", {
+ name: $parent.attr("name"),
+ 'class': "hidden nav nav-list"
+ });
+ var $plink = $parent.children("a");
+ $parent.append($ul);
for (var i = 0; i < mboxes.length; i++) {
var mbname = mboxes[i].name;
- var li = new Element("li", {
+ var $li = $("", {
name: mbname,
- 'class': "droppable folder"
- }).inject(ul);
- var img = new Element("img", {
- 'class': "footer",
- src: static_url("pics/go-down.png")
- }).inject(li);
- var link = new Element("a", {
- name: "loadfolder",
+ 'class': "droppable"
+ });
+ var $link = $("", {
+ name: $plink.attr("name"),
'class': "block",
href: mbname
- }).inject(li);
+ });
var parts = mbname.split(".");
- var displayname = parts[parts.length - 1];
+ var linkcontent = " ";
+ var displayname = linkcontent + parts[parts.length - 1];
+
+ $li.append($link);
+ $ul.append($li);
if (mboxes[i].unseen != undefined) {
- link.addClass("unseen");
- link.set("html", displayname + " (" + mboxes[i].unseen + ")");
+ $link.addClass("unseen");
+ $link.html(displayname + " (" + mboxes[i].unseen + ")");
+ this.unseen_counters[$link.attr("href")] = mboxes[i].unseen;
} else {
- link.set("html", displayname);
+ $link.html(displayname);
}
-
- link.addEvent("click", this.listmailbox_loader.bind(this));
- img.addEvent("click", this.toggle_folder_buttons.bind(this));
}
- this.init_draggables();
- this.toggle_mbox_state(parent.getFirst("div"), ul);
+ this.init_droppables($ul.find(".droppable"), true);
+ this.toggle_mbox_state($parent.children("div"), $ul);
},
/*
* Download sub-mailboxes from the server
*/
get_mailboxes: function(parent) {
- new Request.JSON({
+ $.ajax({
url: this.options.submboxes_url,
- onSuccess: function(resp) {
- if (resp.status == "ko") {
+ dataType: 'json',
+ data: "topmailbox=" + parent.attr("name"),
+ success: $.proxy(function(data) {
+ if (data.status == "ko") {
return;
}
- this.inject_mailboxes(parent, resp.mboxes);
- }.bind(this)
- }).get({topmailbox: parent.get("name")});
- },
-
- /*
- * Enables folders opening/closing
- *
- * Available for folders with subfolders.
- */
- init_folders_browsing: function() {
- $$("div[class*=clickbox]").addEvent("click", function(evt) {
- var div = evt.target;
- var parent = div.getParent();
- var ul = parent.getFirst("ul[name=" + parent.get("name") + "]");
-
- if (ul == undefined) {
- this.get_mailboxes(parent);
- return;
- }
- this.toggle_mbox_state(div, ul);
- evt.stop();
- }.bind(this));
- },
-
- /*
- * Select a particular folder
- */
- select_folder: function(obj) {
- $$("a[name=loadfolder]").each(function(item) {
- item.getParent().removeClass("selected");
- item.getParent().addClass("droppable");
- });
- obj.getParent().removeClass("droppable");
- obj.getParent().addClass("selected");
-
- $$(obj.getParents("ul[class*=hidden]")).each(function(item) {
- item.removeClass("hidden");
- item.addClass("visible");
- $$("li[name=" + item.get("name") + "]").each(function(item) {
- item.setStyle(
- "background",
- "url('" + static_url("pics/folder-open.png") + "') no-repeat"
- );
- });
+ this.inject_mailboxes(parent, data.mboxes);
+ }, this)
});
},
/*
- * Automatic folder listing refresh
- *
- * Called at a regular frequency to make an asynchronous request that
- * retrieves a folder's content (ie. mails)
+ * Open/Close a mailbox with children
*/
- refresh_folder: function() {
- var query = current_anchor.serialized.substring(1);
-
- clearInterval(this.rtimer);
- infobox.show(gettext("Reloading..."), {
- profile : "gray",
- spinner : true
- });
- new Request.JSON({url: query, noCache : true, onSuccess: function(resp) {
- var callback = ($defined(resp.callback)) ? resp.callback : "default";
-
- current_anchor.get_callback(callback)(resp);
- infobox.info(gettext("Done"));
- infobox.hide(1);
- }}).get();
- },
-
- init_automatic_refresh: function() {
- this.rtimer = this.refresh_folder
- .periodical(this.options.refreshRate);
- },
-
- /*
- * Emails table initialization.
- */
- init_emails_table: function() {
- this.emails_table = new HtmlTable($("emails"), {
- selectable: true,
- shiftForMultiSelect: true
- }).addEvents({
- rowFocus: function(tr) {
- clearInterval(this.rtimer);
- }.bind(this),
- rowUnfocus: function(tr) {
- if (this.emails_table._selectedRows.length == 0) {
- this.init_automatic_refresh();
- }
- }.bind(this)
- });
-
- /* The IE way for disabling default selection */
- /* Actually it doesn't work :p */
- $$("tbody>tr").set("unselectable", "on");
-
- if ($("toggleselect")) {
- $("toggleselect").addEvent("click", function(evt) {
- if (evt.target.checked) {
- this.emails_table.selectAll();
- } else {
- this.emails_table.selectNone();
- }
- evt.stopPropagation();
- }.bind(this));
- }
-
- init_sortable_columns();
- update_sortable_column();
-
- this.init_draggables();
-
- $$("tbody>tr").addEvent("dblclick", this.viewmail_loader);
- },
-
- /*
- * Drag & Drop feature
- */
- init_draggables: function(pattern) {
- if (this.dragobjs == undefined) {
- this.dragobjs = new Array();
+ toggle_mbox_state: function($div, $ul) {
+ if ($ul.hasClass("hidden")) {
+ $div.removeClass("collapsed").addClass("expanded");
+ $ul.removeClass("hidden").addClass("visible");
} else {
- this.dragobjs.each(function(item) {
- item.detach();
- delete(item);
- });
- this.dragobjs = new Array();
+ $div.removeClass("expanded").addClass("collapsed");
+ $ul.removeClass("visible").addClass("hidden");
}
-
- $$("td[class*=draggable]").each(function(item) {
- var pid = item.getParent().get("id");
-
- this.dragobjs[pid] = item.makeDraggable({
- droppables: ".droppable"
- }).addEvents({
- beforeStart: this.bstart_dragging.bind(this),
- start: this.start_dragging.bind(this),
- enter: this.enter_droppable,
- leave: this.leave_droppable,
- drop: this.drop_element.bind(this),
- cancel: this.cancel_dragging.bind(this)
- });
- }.bind(this));
},
+ mbox_state_callback: function(e) {
+ e.preventDefault();
+ var $div = $(e.target);
+ var $parent = $div.parent();
+ var $ul = $parent.find('ul[name="' + $parent.attr("name") + '"]');
+
+ if (!$ul.length) {
+ this.get_mailboxes($parent);
+ return;
+ }
+ this.toggle_mbox_state($div, $ul);
+ },
/*
- * 'before start' event callback
+ * Select a particular mailbox
*/
- bstart_dragging: function(item) {
- var dragobj = this.dragobjs[item.getParent().get("id")];
- var block = new Element("div", {id: "draggeditems", 'class': "dragbox"})
- .setStyles({
- top : dragobj.element.getCoordinates()['top'],
- left : dragobj.element.getCoordinates()['left']
- }).inject(document.body);
+ select_mailbox: function(obj) {
+ var $obj = $(obj);
- block.store("parent", dragobj.element);
- dragobj.element = block;
- clearInterval(this.rtimer);
+ $("a[name=loadfolder]").each(function() {
+ var $this = $(this);
+ $this.parent().removeClass("active");
+ $this.parent().addClass("droppable");
+ });
+ $obj.parent().removeClass("droppable");
+ $obj.parent().addClass("active");
+
+ // $$(obj.getParents("ul[class*=hidden]")).each(function(item) {
+ // item.removeClass("hidden");
+ // item.addClass("visible");
+ // $$("li[name=" + item.get("name") + "]").each(function(item) {
+ // item.setStyle(
+ // "background",
+ // "url('" + static_url("pics/folder-open.png") + "') no-repeat"
+ // );
+ // });
+ // });
},
- start_dragging: function(item, event) {
- var tr = event.target.getParent();
-
- if (!this.emails_table.isSelected(tr)) {
- this.emails_table.selectNone();
- this.emails_table.selectRow(tr);
- }
- item.set("html", "Moving " + this.emails_table._selectedRows.length + " messages");
- item.setStyle("display", "block");
+ select_parent_mailbox: function(e) {
+ e.preventDefault();
+ $("a[name=selectfolder]").parent().removeClass("active");
+ $(this).parent().addClass("active");
},
- enter_droppable: function(item, droppable) {
- droppable.addClass("dragging");
- },
-
- leave_droppable: function(item, droppable) {
- droppable.removeClass("dragging");
- },
-
- restore_parent: function(item) {
- var parent = item.retrieve("parent");
- var drag = this.dragobjs[parent.getParent().get("id")];
-
- drag.element = parent;
- this.init_automatic_refresh();
- },
-
- drop_element: function(item, droppable, event) {
- item.dispose();
- if (!droppable) {
- this.restore_parent(item);
- return;
+ /*
+ * Edit the currently selected mailbox. Opens a modal box that
+ * permits to change mailbox's name and more.
+ */
+ edit_mbox: function(e) {
+ var $link = get_target(e, "a");
+ if ($link.hasClass("disabled")) {
+ e.preventDefault();
+ return;
}
- droppable.removeClass("dragging");
- var dest = gethref(droppable.getFirst("a"));
- var msgset = new Array();
+ var $selected = $("#folders li.active").children("a");
- this.emails_table._selectedRows.each(function(item, index) {
- msgset.include(item.get("id"));
- });
- this.simple_request(this.options.move_url, {
- msgset : msgset.join(),
- to : dest
+ modalbox(e, undefined, $link.attr("href") + "?name=" + $selected.attr("href"),
+ $.proxy(this.mboxform_cb, this));
+ },
+
+ /*
+ * Remove the currently selected mailbox.
+ */
+ remove_mbox: function(e) {
+ var $link = get_target(e, "a");
+
+ e.preventDefault();
+ if ($link.hasClass("disabled")) return;
+ if (!confirm(gettext("Remove the selected mailbox?"))) {
+ return;
+ }
+
+ var $selected = $("#folders li.active").children("a");
+
+ $.ajax({
+ url: $link.attr("href") + "?name=" + $selected.attr("href"),
+ dataType: 'json',
+ success: $.proxy(function(data) {
+ if (data.status == "ok") {
+ $("body").notify("success", gettext("Mailbox removed"), 2000);
+ if (this.navobject.getparam("action") == "listmailbox") {
+ $('li[name="' + this.navobject.getparam("name") + '"]').remove();
+ this.select_mailbox($("a[href=INBOX]"));
+ this.navobject.setparam("name", "INBOX").update();
+ }
+ } else {
+ $("body").notify("error", data.respmsg);
+ }
+ }, this)
});
},
- cancel_dragging: function(item) {
- item.dispose();
- this.restore_parent(item);
- },
+ send_mark_request: function(e) {
+ e.preventDefault();
+ if (!this.htmltable.current_selection().length) {
+ return;
+ }
+ var $link = $(e.target);
+ var selection = [];
- /*
- * Bottom left quota bar initialisation.
- */
- init_quota_bar: function() {
- this.quota_pb = new ProgressBar({
- container: $("quotabox"),
- startPercentage: 0,
- boxID: "box",
- percentageID: "perc",
- displayText: true,
- displayID: "quotatext"
+ this.htmltable.current_selection().each(function() {
+ selection.push($(this).attr("id"));
+ });
+ $.ajax({
+ url: $link.attr("href"),
+ data: "ids=" + selection.join(","),
+ dataType: 'json',
+ success: $.proxy(this.mark_callback, this)
});
},
- /*
- *
- */
- page_update: function(response) {
- if (this.gspinner) {
- this.gspinner.hide();
- }
- updatelisting(response);
+ send_mb_action: function(url, cb) {
+ $.ajax({
+ url: url,
+ dataType: 'json',
+ success: $.proxy(function(data) {
+ if (data.status == "ko") {
+ $("body").notify("error", data.respmsg);
+ return;
+ }
+ cb.apply(this, [data]);
+ }, this)
+ });
+ },
+
+ empty: function(e) {
+ e.preventDefault();
+ var $link = $(e.target);
+
+ this.send_mb_action($link.attr("href"), function(data) {
+ this.page_update(data);
+ this.set_unseen_messages(data.mailbox, 0);
+ });
+ },
+
+ delete_message: function(e) {
+ var $link = $(e.target);
+ e.preventDefault();
+ $.ajax({
+ url: $link.attr("href"),
+ dataType: 'json',
+ success: $.proxy(this.delete_callback, this)
+ });
+ },
+
+ display_mode: function(e, value) {
+ e.preventDefault();
+ this.navobject.setparam("links", value).update();
},
/*
- * Webmail actions start here
+ * Action loaders
*/
/*
* Onclick callback used to load the content of a particular
- * folder. (activated when clicking on a folder's name)
+ * mailbox. (activated when clicking on a mailbox's name)
*/
_listmailbox_loader: function(event, obj) {
- event.stop();
- if (obj == undefined) {
+ event.preventDefault();
+ if (obj === undefined) {
obj = $(event.target);
}
- current_anchor.reset().setparams({
+ this.navobject.reset().setparams({
action: "listmailbox",
name: gethref(obj)
}).update();
},
listmailbox_loader: function(event) {
- this.select_folder(event.target);
- this._listmailbox_loader(event, event.target);
+ this.select_mailbox(event.target);
+ this._listmailbox_loader(event, $(event.target));
},
/*
- * Callback for 'folder' action
+ * Special loader used for pagination links as we only need to
+ * update the 'page' parameter.
*/
- listmailbox_callback: function(resp) {
- window.removeEvents("resize");
- this.page_update(resp);
- if (resp.menu != undefined) {
- searchbox_init();
- $$("a[name=compose]").addEvent("click", this.compose_loader);
- $$("a[name=mark-read]")
- .addEvent("click", this.send_mark_request.bind(this));
- $$("a[name=mark-unread]")
- .addEvent("click", this.send_mark_request.bind(this));
- $$("a[name=fdaction]").addEvent("click", function(evt) {
- this.simple_request(evt.target.get("href"), {});
- evt.stop();
- }.bind(this));
- }
- this.init_emails_table();
- },
-
- /*
- * Loader of the 'viemmail' action
- */
- viewmail_loader: function(evt) {
- evt.stop();
- current_anchor.reset().setparams({
- action: "viewmail",
- mailid: this.get("id")
- }).update();
- },
-
- /*
- * Callback of the 'viewmail' action
- */
- viewmail_callback: function(resp) {
- /*wm_updatelisting(resp, "hidden");*/
- this.page_update(resp);
-
- //$$("a[name=back]").addEvent("click", this._listmailbox_loader);
- $$("a[name=reply]").addEvent("click", this.reply_loader);
- $$("a[name=replyall]").addEvent("click", this.reply_loader);
- $$("a[name=forward]").addEvent("click", this.forward_loader);
- $$("a[name=delete]").addEvent("click", function(event) {
- var lnk = event.target;
- event.stop();
- this.simple_request(lnk.get("href"), undefined, function(resp) {
- history.go(-1);
- });
- }.bind(this));
- $$("a[name=activate_links]").addEvent("click", function(evt) {
- evt.stop();
- current_anchor.setparam("links", "1").update();
- });
- $$("a[name=disable_links]").addEvent("click", function(evt) {
- evt.stop();
- current_anchor.setparam("links", "0").update();
- });
- setDivHeight("mailcontent", 5, 0);
+ getpage_loader: function(e) {
+ var $link = $(e.target).parent();
+ e.preventDefault();
+ this.navobject.updateparams($link.attr("href")).update();
},
/*
* Loader of the 'compose' action (called when the associated button
* is clicked)
*/
- compose_loader: function(event) {
- event.stop();
- current_anchor.reset().setparam("action", this.get("href")).update();
+ compose_loader: function(e) {
+ var $link = $(e.target);
+
+ e.preventDefault();
+ this.navobject.reset().setparam("action", $link.attr("href")).update();
+ },
+
+ reply_loader: function(e) {
+ var $link = $(e.target);
+ e.preventDefault();
+ this.navobject.reset().updateparams($link.attr("href")).update();
+ },
+
+ sendmail: function(e) {
+ var $link = $(e.target);
+ var $form = $("#composemail");
+ var args = $form.serialize();
+
+ e.preventDefault();
+ $link.attr("disabled", "disabled");
+ $.ajax({
+ url: $form.attr("action"),
+ data: args,
+ dataType: 'json',
+ type: 'POST',
+ success: $.proxy(this.sendmail_callback, this)
+ });
},
/*
- * Loader of the 'reply' action (called when the associated button
- * is clicked).
+ * Loader of the 'viewmail' action
*/
- reply_loader: function(event, all) {
- event.stop();
- current_anchor.reset().updateparams(this.get("href")).update();
+ viewmail_loader: function(e) {
+ var $tr = $(e.target).parent();
+
+ e.preventDefault();
+ if ($tr.hasClass("unseen")) {
+ var mb = this.navobject.params["name"];
+ this.change_unseen_messages(mb, -1);
+ }
+ this.navobject.reset().setparams({
+ action: "viewmail",
+ mailid: $tr.attr("id")
+ }).update();
},
/*
- * Loader of the 'forward' action (called when the associated button
- * is clicked).
+ * Ajax navigation callbacks
*/
- forward_loader: function(event) {
- event.stop();
- current_anchor.reset().updateparams(this.get("href")).update();
- },
/*
- * Resize the current editor on page resizing.
+ * 'listmailbox' callback
*/
- resize_window_callback: function(event) {
- CKEDITOR.instances[this.editorid]
- .resize("100%", $("body_container").getSize().y);
+ listmailbox_callback: function(resp) {
+ //window.removeEvents("resize");
+ var curmb = this.get_current_mailbox();
+
+ this.enable_mb_actions();
+ for (var idx in this.options.ro_mboxes) {
+ if (curmb == this.options.ro_mboxes[idx]) {
+ this.enable_mb_actions(false);
+ break;
+ }
+ }
+ this.page_update(resp);
+ $("#emails").htmltable();
+ this.htmltable = $("#emails").data("htmltable");
+ this.init_draggables();
},
/*
@@ -536,390 +592,240 @@ var Webmail = new Class({
* It is also shared with other similar actions : reply, forward.
*/
compose_callback: function(resp) {
- //wm_updatelisting(resp);
this.page_update(resp);
-
- var editormode = resp.editor;
-
- if (editormode == "html") {
- window.addEvent("resize", this.resize_window_callback.bind(this));
- var instance = CKEDITOR.instances[editorid];
- if (instance) {
- CKEDITOR.remove(instance);
- }
- CKEDITOR.replace(editorid, {
- customConfig: static_url("js/editor_config.js")
- });
- CKEDITOR.on("instanceReady", function(evt) {
- this.resize_window_callback();
- }.bind(this));
+ if (resp.id != undefined) {
+ this.navobject.setparam("id", resp.id).update(false, true);
}
- if (resp.id) {
- current_anchor.setparam("id", resp.id).update(0, 1);
- }
- $("attachments").addEvent("click", function(evt) {
- SqueezeBox.open(this.get("name"), {
- handler: "iframe",
- size: {x: 350, y: 400},
- closeBtn: false
- });
+ this.position_body();
+ },
+
+ position_body: function() {
+ var $mailheader = $("#mailheader");
+ var top = $mailheader.outerHeight(true);
+
+ $("#body_container").css({
+ top: top + "px"
});
+ },
- /*$$("a[name=back]")
- .removeEvents("click")
- .addEvent("click", this._listmailbox_loader);*/
- $$("a[name=sendmail]")
- .store("editormode", editormode)
- .removeEvents("click")
- .addEvent("click", this.sendmail_callback.bind(this));
+ sendmail_callback: function(data) {
+ if (data.status == "ko") {
+ this.navobject.get_callback("compose")(data);
+ if (data.respmsg != undefined) {
+ $("body").notify("error", data.respmsg);
+ }
+ $("a[name=sendmail]").attr("disabled", null);
+ return;
+ }
+ history.go(-2);
+ $("body").notify("success", gettext("Message sent"), 2000);
},
/*
- * Callback of the 'sendmail' action.
+ * Callback of the 'viewmail' action
*/
- sendmail_callback: function(evt) {
- var link = evt.target;
-
- evt.stop();
- infobox.show(gettext("Sending..."), {
- profile : "gray",
- spinner : true
- });
- disable_link(link);
- $("composemail").set("send", {
- onSuccess: function(resp) {
- resp = JSON.decode(resp);
- if (resp.status == "ko") {
- current_anchor.get_callback("compose")(resp);
- if ($defined(resp.respmsg)) {
- infobox.error(resp.respmsg);
- } else {
- infobox.hide();
- }
- enable_link(link, sendmail_callback);
- return;
- }
- history.go(-2);
- infobox.info(gettext("Done"));
- infobox.hide(1);
- link.eliminate("editormode");
- }.bind(this)
- });
- if (link.retrieve("editormode") == "html") {
- CKEDITOR.instances[editorid].updateElement();
- }
- $("composemail").send();
+ viewmail_callback: function(resp) {
+ this.page_update(resp);
+ $("#listing").css("overflow", "hidden");
},
+ mark_callback: function(data) {
+ if (data.status == "ko") {
+ $("body").notify("error", data.respmsg);
+ return;
+ }
+ if (data.action == "read") {
+ this.htmltable.current_selection().removeClass("unseen");
+ } else {
+ this.htmltable.current_selection().addClass("unseen");
+ }
+ if (data.unseen != undefined && data.mbox) {
+ this.set_unseen_messages(data.mbox, data.unseen);
+ }
+ },
+
+ delete_callback: function(data) {
+ if (data.status == "ok") {
+ history.go(-2);
+ $("body").notify("success", gettext("Message deleted"), 2000);
+ } else {
+ $("body").notify("error", data.respmsg);
+ }
+ },
/*
- * Simple AJAX request
- *
- * Initialize the infobox with a loading message and wait for a JSON
- * encoded answer. The infobox is cleared by the request callback
- * function.
+ * Mailbox form
*/
- simple_request: function(url, params, callback) {
- infobox.show(gettext("Waiting..."), {
- profile: "gray",
- spinner: true
- });
- new Request.JSON({
- url : url,
- onSuccess : function(response) {
- if (response.status == "ok") {
- if (response.next == undefined) {
- if (callback != undefined) {
- callback(response);
- } else {
- current_anchor.get_callback("listmailbox")(response);
- }
- }
- infobox.info(gettext("Done"));
- if ($defined(response.next)) {
- (function(response) {
- current_anchor.parse_string(response.next).update();
- select_folder($$("a[href=" + current_anchor.getbaseurl() + "]"));
- }).delay(500, this, response);
- } else {
- infobox.hide(1);
- }
- } else {
- infobox.error(response.respmsg);
- }
- }
- }).get(params);
- }
-});
+ mboxform_cb: function() {
+ $(".submit").one('click', $.proxy(function(e) {
+ var $link = $("#folders2 li.active").children("a");
+ simple_ajax_form_post(e, {
+ formid: "mboxform",
+ error_cb: this.mboxform_cb,
+ extradata: ($link.length) ? "parent_folder=" + $link.attr("href") : ""
+ });
+ }, this));
+ },
-/*
- * Globals
- */
-var rtimer = null;
-var editorid = "id_body";
-
-/*
- * Enables folders opening/closing
- *
- * Available for folders with subfolders.
- */
-function init_folders_browsing() {
- $$("div[class*=clickbox]").addEvent("click", function(evt) {
- var parent = this.getParent();
- var ul = parent.getFirst("ul[name=" + parent.get("name") + "]");
-
- if (!$defined(ul)) {
- return;
- }
- if (ul.hasClass("hidden")) {
- this.removeClass("collapsed").addClass("expanded");
- ul.removeClass("hidden").addClass("visible");
- } else {
- this.removeClass("expanded").addClass("collapsed");
- ul.removeClass("visible").addClass("hidden");
- }
- evt.stop();
- });
-}
-
-/*
- * Select a particular folder
- */
-function select_folder(obj) {
- $$("a[name=loadfolder]").each(function(item) {
- item.getParent().removeClass("selected");
- item.getParent().addClass("droppable");
- });
- obj.getParent().removeClass("droppable");
- obj.getParent().addClass("selected");
-
- $$(obj.getParents("ul[class*=hidden]")).each(function(item) {
- item.removeClass("hidden");
- item.addClass("visible");
- $$("li[name=" + item.get("name") + "]").each(function(item) {
- item.setStyle("background",
- "url('" + static_url("pics/folder-open.png") + "') no-repeat");
- });
- });
-}
-
-/*
- * Callback of the 'viewmail' action
- */
-function viewmail_cb(resp) {
- wm_updatelisting(resp, "hidden");
- $$("a[name=back]").addEvent("click", loadFolder);
- $$("a[name=reply]").addEvent("click", reply_loader);
- $$("a[name=replyall]").addEvent("click", replyall_loader);
- $$("a[name=forward]").addEvent("click", forward_loader);
- $$("a[name=delete]").addEvent("click", function(event) {
- var lnk = event.target;
- event.stop();
- simple_request(lnk.get("href"));
- });
- $$("a[name=activate_links]").addEvent("click", function(evt) {
- evt.stop();
- current_anchor.setparam("links", "1").update();
- });
- $$("a[name=disable_links]").addEvent("click", function(evt) {
- evt.stop();
- current_anchor.setparam("links", "0").update();
- });
- setDivHeight("mailcontent", 5, 0);
-}
-
-/*
- * Loader of the 'compose' action (called when the associated button
- * is clicked)
- */
-function compose_loader(event) {
- event.stop();
- current_anchor.baseurl("compose").update();
-}
-
-function resize_window_callback(event) {
- CKEDITOR.instances["id_body"].resize("100%", $("body_container").getSize().y);
-}
-
-/*
- * Callback of the 'sendmail' action.
- */
-function sendmail_callback(evt) {
- evt.stop();
- infobox.show(gettext("Sending..."), {
- profile : "gray",
- spinner : true
- });
- disable_link(this);
- $("composemail").set("send", {
- onSuccess: function(resp) {
- resp = JSON.decode(resp);
- if (resp.status == "ko") {
- current_anchor.get_callback("compose")(resp);
- if ($defined(resp.respmsg)) {
- infobox.error(resp.respmsg);
- } else {
- infobox.hide();
- }
- enable_link(this, sendmail_callback);
+ /*
+ * Attachments form
+ */
+ attachments_init: function() {
+ $("#submit").click(function(e) {
+ e.preventDefault();
+ if ($("#id_attachment").attr("value") == "") {
return;
}
- current_anchor.parse_string(resp.url, true).setparams(navparams);
- current_anchor.update();
- this.eliminate("editormode");
- }.bind(this)
- });
- if (this.retrieve("editormode") == "html") {
- CKEDITOR.instances[editorid].updateElement();
- }
- $("composemail").send();
-}
+ $("#upload_status").css("display", "block");
+ $("#submit").attr("disabled", "disabled");
+ $("#uploadfile").submit();
+ });
+ $("a[name=delattachment]").click(this.del_attachment);
+ $(".modal").one("hide", this.close_attachments);
+ },
-/*
- * Callback of the 'compose' action
- */
-function compose_callback(resp) {
- wm_updatelisting(resp);
+ _reset_upload_form: function() {
+ $("#upload_status").css("display", "none");
+ $("#submit").attr("disabled", null);
+ },
- var editormode = resp.editor;
+ upload_success: function(fname, tmpname) {
+ this._reset_upload_form();
+ var $delbtn = $("", {
+ name: "delattachment",
+ href: this.options.delattachment_url + "?name=" + tmpname,
+ html: ""
+ });
+ var $label = $("", {html: fname});
+ var $div = $("").append($delbtn, $label);
- if (editormode == "html") {
- window.addEvent("resize", resize_window_callback);
- var instance = CKEDITOR.instances[editorid];
- if (instance) {
- CKEDITOR.remove(instance);
- }
- CKEDITOR.replace(editorid, {
- customConfig: static_url("js/editor_config.js")
- });
- CKEDITOR.on("instanceReady", function(evt) {
- resize_window_callback();
- });
- }
- if (resp.id) {
- current_anchor.setparam("id", resp.id).update(0, 1);
- }
- $("attachments").addEvent("click", function(evt) {
- SqueezeBox.open(this.get("name"), {
- handler: "iframe",
- size: {x: 350, y: 400},
- closeBtn: false
- });
- });
+ $delbtn.click(this.del_attachment);
+ $("#id_attachment").attr("value", "");
+ $("#attachment_list").append($div);
+ },
- $$("a[name=back]")
- .removeEvents("click")
- .addEvent("click", loadFolder);
- $$("a[name=sendmail]")
- .store("editormode", editormode)
- .removeEvents("click")
- .addEvent("click", sendmail_callback);
-}
+ upload_error: function(msg) {
+ this._reset_upload_form();
+ $(".modal-header").notify('error', msg);
+ },
-/*
- * Loader of the 'reply' action (called when the associated button
- * is clicked).
- */
-function reply_loader(event) {
- event.stop();
- location.hash += event.target.get("href");
-}
+ del_attachment: function(e) {
+ e.preventDefault();
+ var $this = $(this);
-/*
- * Loader of the 'replyall' action (called when the associated button
- * is clicked).
- */
-function replyall_loader(event) {
- event.stop();
- location.hash += event.target.get("href") + "?all=1";
-}
+ $.ajax({
+ url: $this.attr("href"),
+ success: function() {
+ $this.parent().remove();
+ }
+ });
+ },
-/*
- * Loader of the 'forward' action (called when the associated button
- * is clicked).
- */
-function forward_loader(event) {
- event.stop();
- location.hash += event.target.get("href");
-}
+ close_attachments: function() {
+ var nfiles = 0;
+ var shortlist = "";
+ var html;
-/*
- * Onclick callback used to load the content of a particular
- * folder. (activated when clicking on a folder's name)
- */
-function loadFolder(event, obj) {
- event.stop();
- if (!$defined(obj)) {
- obj = $(event.target);
- }
- current_anchor.parse_string(gethref(obj), true).setparams(navparams);
- current_anchor.update();
-}
+ $("a[name=delattachment]").each(function() {
+ var $this = $(this);
+ var $label = $this.next("label");
-function foldercallback(event) {
- select_folder(event.target);
- loadFolder(event, event.target);
-}
-
-/*
- * Automatic folder listing refresh
- *
- * Called at a regular frequency to make an asynchronous request that
- * retrieves a folder's content (ie. mails)
- */
-function refreshFolder() {
- var query = current_anchor.serialized.substring(1);
-
- clearInterval(rtimer);
- infobox.show(gettext("Reloading..."), {
- profile : "gray",
- spinner : true
- });
- new Request.JSON.mdb({
- url: query,
- noCache : true,
- onSuccess: function(resp) {
- var callback = ($defined(resp.callback)) ? resp.callback : "default";
-
- current_anchor.get_callback(callback)(resp);
- infobox.info(gettext("Done"));
- infobox.hide(1);
- }
- }).get();
-}
-
-/*
- * Simple AJAX request
- *
- * Initialize the infobox with a loading message and wait for a JSON
- * encoded answer. The infobox is cleared by the request callback
- * function.
- */
-function simple_request(url, params) {
- infobox.show(gettext("Waiting..."), {
- profile: "gray",
- spinner: true
- });
- new Request.JSON.mdb({
- url : url,
- onSuccess : function(response) {
- if (response.status == "ok") {
- if (!$defined(response.next)) {
- current_anchor.get_callback("folder")(response);
+ nfiles++;
+ if (nfiles <= 2) {
+ if (shortlist != "") {
+ shortlist += ", ";
+ } else {
+ shortlist = "(";
+ }
+ shortlist += $label.html();
+ return;
+ }
+ if (nfiles == 3) {
+ shortlist += ", ...";
+ }
+ });
+ if (shortlist != "") {
+ shortlist += ")";
}
- infobox.info(gettext("Done"));
- if ($defined(response.next)) {
- (function(response) {
- current_anchor.parse_string(response.next).update();
- select_folder($$("a[href=" + current_anchor.getbaseurl() + "]"));
- }).delay(500, this, response);
- } else {
- infobox.hide(1);
- }
- } else {
- infobox.error(response.respmsg);
- }
+ html = interpolate(ngettext("%s file", "%s files", nfiles), [nfiles]);
+ html += " " + shortlist + "";
+ $("#list").html(html);
+ },
+
+ /*
+ * Drag & Drop feature to move message(s) between mailboxes
+ */
+ init_draggables: function() {
+ var plug = this;
+
+ $("td[name=select]").draggable({
+ opacity: 0.8,
+ helper: function(e) {
+ var $this = $(this);
+ var $tr = $this.parent();
+
+ if (!plug.htmltable.is_selected($tr)) {
+ plug.htmltable.select_row($tr);
+ }
+
+ var nmsgs = plug.htmltable.current_selection().length;
+
+ var $dragbox = $("", {
+ id: "draggeditems",
+ 'class': "well dragbox"
+ })
+ .appendTo($(document.body))
+ .css({
+ top: $this.offset().top,
+ left: $this.offset().left
+ });
+ $dragbox.html(interpolate(ngettext("Moving %s message",
+ "Moving %s messages", nmsgs), [nmsgs]));
+ return $dragbox;
+ }
+ });
+ },
+
+ init_droppables: function(set, greedy) {
+ var plug = this;
+ var $set = (set === undefined) ? $(".droppable") : set;
+
+ $set.droppable({
+ greedy: true,
+ hoverClass: "active",
+
+ drop: function(e, ui) {
+ var $this = $(this);
+ var selection = new Array();
+ var unseen_cnt = 0;
+ var from = plug.get_current_mailbox();
+ var to = gethref($this.find("a"));
+
+ plug.htmltable.current_selection().each(function() {
+ var $this = $(this);
+ selection.push($this.attr("id"));
+ if ($this.hasClass("unseen")) {
+ unseen_cnt++;
+ }
+ });
+ $.ajax({
+ url: plug.options.move_url,
+ data: "msgset=" + selection.join() + "&to=" + to,
+ dataType: 'json',
+ success: function(data) {
+ if (data.status == "ok") {
+ if (unseen_cnt) {
+ plug.change_unseen_messages(from, -unseen_cnt);
+ plug.change_unseen_messages(to, unseen_cnt);
+ }
+ plug.listmailbox_callback(data);
+ } else {
+ $("body").notify("error", data.respmsg);
+ }
+ }
+ });
+ }
+ });
}
- }).get(params);
-}
\ No newline at end of file
+};
diff --git a/extensions/webmail/templates/webmail/folder.html b/extensions/webmail/templates/webmail/folder.html
index 62af3b982..eea27a94d 100644
--- a/extensions/webmail/templates/webmail/folder.html
+++ b/extensions/webmail/templates/webmail/folder.html
@@ -1,49 +1,10 @@
-{% extends "layout_simple.html" %}
-{% load i18n %}
-{% block html_head %}
-
-
-
-
-{% endblock %}
-{% block content %}
-{{ title }}
-{{ error }}
-
+{% extends "common/generic_modal_form.html" %}
+{% load i18n webextras %}
+{% block extrafields %}
+
+
+
+ {% print_folders folders selected withunseen selectonly %}
+
+
{% endblock %}
diff --git a/extensions/webmail/templates/webmail/index.html b/extensions/webmail/templates/webmail/index.html
index 3f1208fc6..5eb8af0d6 100644
--- a/extensions/webmail/templates/webmail/index.html
+++ b/extensions/webmail/templates/webmail/index.html
@@ -1,230 +1,42 @@
-{% extends "common/email_listing.html" %}
-{% load i18n %}
+{% extends "fixed.html" %}
+{% load i18n libextras %}
{% block html_head %}
-
-
-
+
+
+
+
-{{ block.super }}
{% endblock %}
-{% block js %}
- /*quota_pb = new ProgressBar({
- container: $("quotabox"),
- startPercentage: 0,
- boxID: "box",
- percentageID: "perc",
- displayText: true,
- displayID: "quotatext"
- });
-
- current_anchor.register_callback("viewmail", viewmail_cb);
- current_anchor.register_callback("compose", compose_callback);
- current_anchor.register_callback("reply", compose_callback);
- current_anchor.register_callback("replyall", compose_callback);
- current_anchor.register_callback("forward", compose_callback);
-
- window.addEvent("pageRefresh", function() {
- if (rtimer) {
- clearInterval(rtimer);
- rtimer = null;
- }
- });*/
-
- new Webmail({
- refreshRate: {{ refreshrate }},
- modify_url: "{% url modoboa.extensions.webmail.views.editfolder %}",
- delete_url: "{% url modoboa.extensions.webmail.views.delfolder %}",
- move_url: "{% url modoboa.extensions.webmail.views.move %}",
- submboxes_url: "{% url modoboa.extensions.webmail.views.submailboxes %}"
- });
-
- current_anchor.register_callback("folder", function(resp) {
- wm_updatelisting(resp);
- rtimer = refreshFolder.periodical({{ refreshrate }});
- searchbox_init();
- update_sortable_column();
-
- var emails_table = new HtmlTable($("emails"), {
- selectable: true,
- shiftForMultiSelect: true
- }).addEvents({
- rowFocus: function(tr) {
- clearInterval(rtimer);
- },
- rowUnfocus: function(tr) {
- if (this._selectedRows.length == 0) {
- rtimer = refreshFolder.periodical({{ refreshrate }});
- }
- }
- });
-
- /* The IE way for disabling default selection */
- /* Actually it doesn't work :p */
- $$("tbody>tr").set("unselectable", "on");
-
- bstart_dragging = function(item) {
- var block = new Element("div", {id: "draggeditems"})
- .setStyles({"position" : "absolute",
- "opacity" : 0.8,
- "width" : "200px",
- "padding" : "5px",
- "text-align" : "center",
- "height" : "25px",
- "border" : "1px solid #333",
- "background" : "white",
- display: "none",
- "z-index" : 3,
- top : this.element.getCoordinates()['top'],
- left : this.element.getCoordinates()['left']})
- .inject(document.body);
- block.store("parent", this.element);
- this.element = block;
- clearInterval(rtimer);
- };
-
- start_dragging = function(item) {
- var tr = this.element.retrieve("parent").getParent();
-
- if (!emails_table.isSelected(tr)) {
- emails_table.selectNone();
- emails_table.selectRow(tr);
- }
- item.set("html", "Moving " + emails_table._selectedRows.length + " messages");
- this.element.setStyle("display", "block");
- };
-
- enter_droppable = function(item, droppable) {
- droppable.addClass("dragging");
- };
-
- leave_droppable = function(item, droppable) {
- droppable.removeClass("dragging");
- };
-
- restore_parent = function(drag, item) {
- var parent = item.retrieve("parent");
-
- drag.element = parent;
- rtimer = refreshFolder.periodical({{ refreshrate }});
- };
-
- drop_element = function(item, droppable, event) {
- this.element.dispose();
- delete(this.element);
- if (!droppable) {
- restore_parent(this, item);
- return;
- }
- droppable.removeClass("dragging");
- dest = gethref(droppable.getFirst("a"));
- msgset = new Array();
- emails_table._selectedRows.each(function(item, index) {
- msgset.include(item.get("id"));
- });
- {% url modoboa.extensions.webmail.views.move as moveurl %}
- simple_request("{{ moveurl }}", {msgset : msgset.join(), to : dest});
- };
-
- cancel_dragging = function(item) {
- this.element.dispose();
- delete(this.element);
- restore_parent(this, item);
- };
-
- $$("td[class*=draggable]").each(function(item) {
- new Drag.Move(item, {
- droppables: ".droppable"
- }).addEvents({
- beforeStart: bstart_dragging,
- start: start_dragging,
- enter: enter_droppable,
- leave: leave_droppable,
- drop: drop_element,
- cancel: cancel_dragging
- });
- });
-
- buildmarkrequest = function(evt) {
- evt.stop();
- if (!emails_table._selectedRows.length) {
- return;
- }
- var ids = new Array();
- emails_table._selectedRows.each(function(item, index) {
- ids.include(item.get("id"));
- });
- simple_request(evt.target.get("href"), {ids : ids.join()});
- };
- $$("a[name=mark-read]").addEvent("click", buildmarkrequest);
- $$("a[name=mark-unread]").addEvent("click", buildmarkrequest);
-
- $$("a[name=fdaction]").addEvent("click", function(evt) {
- simple_request(evt.target.get("href"), {});
- evt.stop();
- });
-
- if ($("toggleselect")) {
- $("toggleselect").addEvent("click", function(evt) {
- if (evt.target.checked) {
- emails_table.selectAll();
- } else {
- emails_table.selectNone();
- }
- });
- }
- init_sortable_columns();
- $$("tbody>tr").addEvent("dblclick", viewmail);
- });
+{% block fixed_content %}
+
+
+
+
+
{% endblock %}
-{% block middletitle %}{% trans "Webmail" %}{% endblock %}
-{% block leftcol %}
-{{ mboxes }}
-{% endblock %}
-{% block menu %}{{ menu }}{% endblock %}
-{% block footer %}
-{% trans "Mailbox quota" %}
-{{ quota }}
-{{ block.super }}
+{% block footerleft %}
+
+
+
+
+
{% endblock %}
+
diff --git a/extensions/webmail/templatetags/webextras.py b/extensions/webmail/templatetags/webextras.py
index 3d4b92302..721e32c19 100644
--- a/extensions/webmail/templatetags/webextras.py
+++ b/extensions/webmail/templatetags/webextras.py
@@ -105,9 +105,8 @@ def listmailbox_menu(selection, folder, user):
]
if folder == parameters.get_user(user, "TRASH_FOLDER"):
entries[2]["menu"] += [
- {"name" : "fdaction",
+ {"name" : "empty",
"label" : _("Empty folder"),
- "img" : static_url("pics/clear.png"),
"url" : reverse(webmail.views.empty, args=[folder])}
]
searchbar = render_to_string('common/email_searchbar.html', {
@@ -167,19 +166,19 @@ def mboxes_menu():
{"name" : "newmbox",
"url" : reverse(webmail.views.newfolder),
"img" : "icon-plus",
- "label" : "",
+ "title" : _("Create a new mailbox"),
"modal" : True,
"modalcb" : "webmail.mboxform_cb",
"class" : "btn btn-mini"},
{"name" : "editmbox",
"url" : reverse(webmail.views.editfolder),
"img" : "icon-edit",
- "label" : "",
+ "title" : _("Edit the selected mailbox"),
"class" : "btn btn-mini"},
{"name" : "removembox",
"url" : reverse(webmail.views.delfolder),
"img" : "icon-remove",
- "label" : "",
+ "title" : _("Remove the selected mailbox"),
"class" : "btn btn-mini"}
]
diff --git a/extensions/webmail/views.py b/extensions/webmail/views.py
index f7f93146c..5a9d9dea6 100644
--- a/extensions/webmail/views.py
+++ b/extensions/webmail/views.py
@@ -214,11 +214,12 @@ def mark(request, name):
@login_required
@needs_mailbox()
def empty(request, name):
- if name == parameters.get_user(request.user, "TRASH_FOLDER"):
- get_imapconnector(request).empty(name)
+ if name != parameters.get_user(request.user, "TRASH_FOLDER"):
+ raise WebmailError(_("Invalid request"))
+ get_imapconnector(request).empty(name)
content = "%s
" % _("Empty mailbox")
return ajax_simple_response(dict(
- status="ok", listing=content
+ status="ok", listing=content, mailbox=name
))
@login_required
@@ -620,13 +621,12 @@ def newindex(request):
response["refreshrate"] = \
int(parameters.get_user(request.user, "REFRESH_INTERVAL"))
response["quota"] = ImapListing.computequota(imapc)
- if response["quota"] < 50:
- response["quotalevel"] = "success"
- elif response["quotalevel"] < 80:
- response["quotalevel"] = "warning"
- else:
- response["quotalevel"] = "danger"
- return _render(request, "webmail/index2.html", response)
+ response["ro_mboxes"] = ["INBOX", "Junk",
+ parameters.get_user(request.user, "SENT_FOLDER"),
+ parameters.get_user(request.user, "TRASH_FOLDER"),
+ parameters.get_user(request.user, "DRAFTS_FOLDER")]
+
+ return _render(request, "webmail/index.html", response)
if action in ["reply", "forward"]:
action = "compose"
diff --git a/lib/templatetags/libextras.py b/lib/templatetags/libextras.py
index f71ecbc12..7418d2d56 100644
--- a/lib/templatetags/libextras.py
+++ b/lib/templatetags/libextras.py
@@ -35,6 +35,9 @@ def join(items, sep=','):
res += "%s : '%s'" % (k, v)
return res
+@register.simple_tag
+def tolist(values):
+ return "[%s]" % ",".join(map(lambda v: '"%s"' % v, values))
@register.simple_tag
def display_messages(msgs):
@@ -134,7 +137,7 @@ def alert(msg, typ):
@register.simple_tag
def render_link(linkdef, mdclass=None):
- t = Template("""