From 77de23fa939338546a3e049459ffd29edd9058c2 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Sun, 11 Nov 2012 04:32:05 -0500 Subject: [PATCH] Added cross-task 'refresh' request for system state updates --- CHANGELOG | 2 + index.php | 4 +- program/steps/mail/check_recent.inc | 10 +++- program/include/rcmail.php | 5 ++ program/localization/en_US/messages.inc | 1 program/steps/mail/func.inc | 1 program/js/app.js | 83 ++++++++++++++++++++++++++++------------- 7 files changed, 74 insertions(+), 32 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 02fe0e2..dea6c19 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ CHANGELOG Roundcube Webmail =========================== +- Improved keep-alive action. Now the interval is based on session_lifetime +- Added cross-task 'refresh' request for system state updates - Fix AREA links handling (#1488792) - Better client-side timezone detection using the jsTimezoneDetect library (#1488725) - Fix possible HTTP DoS on error in keep-alive requests (#1488782) diff --git a/index.php b/index.php index 0ad371a..05fc641 100644 --- a/index.php +++ b/index.php @@ -249,7 +249,6 @@ $RCMAIL->set_task($plugin['task']); $RCMAIL->action = $plugin['action']; - // handle special actions if ($RCMAIL->action == 'keep-alive') { $OUTPUT->reset(); @@ -282,7 +281,8 @@ else if (($stepfile = $RCMAIL->get_action_file()) && is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/'.$stepfile) ) { - include $incfile; + // include action file only once (in case it don't exit) + include_once $incfile; $redirects++; } else { diff --git a/program/include/rcmail.php b/program/include/rcmail.php index a755aa8..04b87e4 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -332,7 +332,7 @@ $this->output->set_charset(RCMAIL_CHARSET); // add some basic labels to client - $this->output->add_label('loading', 'servererror', 'requesttimedout'); + $this->output->add_label('loading', 'servererror', 'requesttimedout', 'refreshing'); return $this->output; } @@ -770,6 +770,7 @@ } } + /** * Registers action aliases for current task * @@ -784,6 +785,7 @@ } } + /** * Returns current action filename * @@ -798,6 +800,7 @@ return strtr($this->action, '-', '_') . '.inc'; } + /** * Fixes some user preferences according to namespace handling change. * Old Roundcube versions were using folder names with removed namespace prefix. diff --git a/program/js/app.js b/program/js/app.js index f372c0f..25fddf1 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -482,7 +482,8 @@ this.onloads[i](); } - // start keep-alive interval + // start keep-alive and refresh intervals + this.start_refresh(); this.start_keepalive(); }; @@ -878,10 +879,6 @@ case 'firstmessage': if (this.env.first_uid) this.show_message(this.env.first_uid); - break; - - case 'checkmail': - this.check_for_recent(true); break; case 'compose': @@ -2059,6 +2056,15 @@ else if (this.task == 'mail') this.list_mailbox(this.env.mailbox, page); } + }; + + // sends request to check for recent messages + this.checkmail = function() + { + var lock = this.set_busy(true, 'checkingmail'), + params = this.check_recent_params(); + + this.http_request('check-recent', params, lock); }; // list messages of a specific mailbox using filter @@ -6125,7 +6131,7 @@ // trigger plugin hook var result = this.triggerEvent('request'+action, postdata); if (result !== undefined) { - // abort if one the handlers returned false + // abort if one of the handlers returned false if (result === false) return false; else @@ -6237,6 +6243,7 @@ } break; + case 'refresh': case 'check-recent': case 'getunread': case 'search': @@ -6469,13 +6476,25 @@ // starts interval for keep-alive signal this.start_keepalive = function() { - if (!this.env.session_lifetime || this.env.framed || this.task == 'login' || this.env.action == 'print') + if (!this.env.session_lifetime || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print') return; - if (this._int) - clearInterval(this._int); + if (this._keepalive) + clearInterval(this._keepalive); - this._int = setInterval(function(){ ref.keep_alive(); }, this.env.session_lifetime * 0.5 * 1000); + this._keepalive = setInterval(function(){ ref.keep_alive(); }, this.env.session_lifetime * 0.5 * 1000); + }; + + // starts interval for refresh signal + this.start_refresh = function() + { + if (!this.env.keep_alive || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print') + return; + + if (this._refresh) + clearInterval(this._refresh); + + this._refresh = setInterval(function(){ ref.refresh(); }, this.env.keep_alive * 1000); }; // sends keep-alive signal @@ -6485,27 +6504,39 @@ this.http_request('keep-alive'); }; - // sends request to check for recent messages - this.check_for_recent = function(refresh) + // sends refresh signal + this.refresh = function() { - if (this.busy) + if (this.busy) { + // try again after 10 seconds + setTimeout(function(){ ref.refresh(); ref.start_refresh(); }, 10000); return; - - var lock, url = {_mbox: this.env.mailbox}; - - if (refresh) { - lock = this.set_busy(true, 'checkingmail'); - url._refresh = 1; } - if (this.gui_objects.messagelist) - url._list = 1; - if (this.gui_objects.quotadisplay) - url._quota = 1; - if (this.env.search_request) - url._search = this.env.search_request; + var params = {}, lock = this.set_busy(true, 'refreshing'); - this.http_request('check-recent', url, lock); + if (this.task == 'mail' && this.gui_objects.mailboxlist) + params = this.check_recent_params(); + + // plugins should bind to 'requestrefresh' event to add own params + this.http_request('refresh', params, lock); + }; + + // returns check-recent request parameters + this.check_recent_params = function() + { + var params = {_mbox: this.env.mailbox}; + + if (this.gui_objects.mailboxlist) + params._folderlist = 1; + if (this.gui_objects.messagelist) + params._list = 1; + if (this.gui_objects.quotadisplay) + params._quota = 1; + if (this.env.search_request) + params._search = this.env.search_request; + + return params; }; diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc index cabc999..a858d0a 100644 --- a/program/localization/en_US/messages.inc +++ b/program/localization/en_US/messages.inc @@ -37,6 +37,7 @@ $messages['nomessagesfound'] = 'No messages found in this mailbox.'; $messages['loggedout'] = 'You have successfully terminated the session. Good bye!'; $messages['mailboxempty'] = 'Mailbox is empty.'; +$messages['refreshing'] = 'Refreshing...'; $messages['loading'] = 'Loading...'; $messages['uploading'] = 'Uploading file...'; $messages['uploadingmany'] = 'Uploading files...'; diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc index 1a1b08c..90d17c1 100644 --- a/program/steps/mail/check_recent.inc +++ b/program/steps/mail/check_recent.inc @@ -19,8 +19,14 @@ +-----------------------------------------------------------------------+ */ +// If there's no folder or messages list, there's nothing to update +// This can happen on 'refresh' request +if (empty($_REQUEST['_folderlist']) && empty($_REQUEST['_list'])) { + return; +} + $current = $RCMAIL->storage->get_folder(); -$check_all = !empty($_GET['_refresh']) || (bool)$RCMAIL->config->get('check_all_folders'); +$check_all = $RCMAIL->action != 'refresh' || (bool)$RCMAIL->config->get('check_all_folders'); // list of folders to check if ($check_all) { @@ -101,7 +107,5 @@ } } } - -$RCMAIL->plugins->exec_hook('keep_alive', array()); $OUTPUT->send(); diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index f128a38..374ab75 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -1810,6 +1810,7 @@ // register action aliases $RCMAIL->register_action_map(array( + 'refresh' => 'check_recent.inc', 'preview' => 'show.inc', 'print' => 'show.inc', 'moveto' => 'move_del.inc', -- Gitblit v1.9.1