summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2013-12-23 11:33:41 +0100
committerAleksander Machniak <alec@alec.pl>2013-12-23 11:33:41 +0100
commitac0fc383fd43e8955b0ab22f70463159b14c74b0 (patch)
tree3b0c5aafc0e8b6cb5b58d671f5f048ecb100f9ce
parent6b2b2eca5fa48720c4e5b31b9aae200a185dfc0e (diff)
Fix so message flags modified by another client are applied on the list on refresh (#1485186)
-rw-r--r--CHANGELOG1
-rw-r--r--program/js/app.js19
-rw-r--r--program/lib/Roundcube/rcube_imap.php35
-rw-r--r--program/lib/Roundcube/rcube_storage.php12
-rw-r--r--program/steps/mail/check_recent.inc18
-rw-r--r--program/steps/mail/list.inc11
-rw-r--r--program/steps/mail/search.inc7
7 files changed, 99 insertions, 4 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b1eca46f2..ff09b2f62 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
+- Fix so message flags modified by another client are applied on the list on refresh (#1485186)
- Fix broken text/* attachments when forwarding/editing a message (#1489426)
- Improved minified files handling, added css minification (#1486988)
- Fix handling of X-Forwarded-For header with multiple addresses (#1489481)
diff --git a/program/js/app.js b/program/js/app.js
index 138fcbb13..a001a3bff 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -6923,6 +6923,16 @@ function rcube_webmail()
case 'refresh':
case 'check-recent':
+ // update message flags
+ $.each(this.env.recent_flags || {}, function(uid, flags) {
+ ref.set_message(uid, 'deleted', flags.deleted);
+ ref.set_message(uid, 'replied', flags.answered);
+ ref.set_message(uid, 'unread', !flags.seen);
+ ref.set_message(uid, 'forwarded', flags.forwarded);
+ ref.set_message(uid, 'flagged', flags.flagged);
+ });
+ delete this.env.recent_flags;
+
case 'getunread':
case 'search':
this.env.qsearch = null;
@@ -7246,13 +7256,18 @@ function rcube_webmail()
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;
+ if (this.gui_objects.messagelist) {
+ params._list = 1;
+
+ // message uids for flag updates check
+ params._uids = $.map(this.message_list.rows, function(row, uid) { return uid; }).join(',');
+ }
+
return params;
};
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index f1363caf7..4c3bf6fcd 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -680,6 +680,41 @@ class rcube_imap extends rcube_storage
/**
+ * Public method for listing message flags
+ *
+ * @param string $folder Folder name
+ * @param array $uids Message UIDs
+ * @param int $mod_seq Optional MODSEQ value (of last flag update)
+ *
+ * @return array Indexed array with message flags
+ */
+ public function list_flags($folder, $uids, $mod_seq = null)
+ {
+ if (!strlen($folder)) {
+ $folder = $this->folder;
+ }
+
+ if (!$this->check_connection()) {
+ return array();
+ }
+
+ // @TODO: when cache was synchronized in this request
+ // we might already have asked for flag updates, use it.
+
+ $flags = $this->conn->fetch($folder, $uids, true, array('FLAGS'), $mod_seq);
+ $result = array();
+
+ if (!empty($flags)) {
+ foreach ($flags as $message) {
+ $result[$message->uid] = $message->flags;
+ }
+ }
+
+ return $result;
+ }
+
+
+ /**
* Public method for listing headers
*
* @param string $folder Folder name
diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php
index e697b2c73..ca65af1cb 100644
--- a/program/lib/Roundcube/rcube_storage.php
+++ b/program/lib/Roundcube/rcube_storage.php
@@ -360,6 +360,18 @@ abstract class rcube_storage
/**
+ * Public method for listing message flags
+ *
+ * @param string $folder Folder name
+ * @param array $uids Message UIDs
+ * @param int $mod_seq Optional MODSEQ value
+ *
+ * @return array Indexed array with message flags
+ */
+ abstract function list_flags($folder, $uids, $mod_seq = null);
+
+
+ /**
* Public method for listing headers.
*
* @param string $folder Folder name
diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc
index 3aa7b3e9c..60da68a96 100644
--- a/program/steps/mail/check_recent.inc
+++ b/program/steps/mail/check_recent.inc
@@ -114,6 +114,24 @@ foreach ($a_mailboxes as $mbox_name) {
$OUTPUT->command('update_selection');
}
}
+ // handle flag updates
+ else if ($is_current && ($uids = rcube_utils::get_input_value('_uids', rcube_utils::INPUT_GPC))) {
+ $data = $RCMAIL->storage->folder_data($mbox_name);
+
+ if (empty($_SESSION['list_mod_seq']) || $_SESSION['list_mod_seq'] != $data['HIGHESTMODSEQ']) {
+ $flags = $RCMAIL->storage->list_flags($mbox_name, explode(',', $uids), $_SESSION['list_mod_seq']);
+ foreach ($flags as $idx => $row) {
+ $flags[$idx] = array_change_key_case(array_map('intval', $row));
+ }
+
+ // remember last HIGHESTMODSEQ value (if supported)
+ if (!empty($data['HIGHESTMODSEQ'])) {
+ $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ'];
+ }
+
+ $RCMAIL->output->set_env('recent_flags', $flags);
+ }
+ }
}
// trigger refresh hook
diff --git a/program/steps/mail/list.inc b/program/steps/mail/list.inc
index fe7991c29..91c53e852 100644
--- a/program/steps/mail/list.inc
+++ b/program/steps/mail/list.inc
@@ -23,8 +23,8 @@ if (!$OUTPUT->ajax_call) {
return;
}
-$save_arr = array();
-$dont_override = (array) $RCMAIL->config->get('dont_override');
+$save_arr = array();
+$dont_override = (array) $RCMAIL->config->get('dont_override');
// is there a sort type for this request?
if ($sort = rcube_utils::get_input_value('_sort', rcube_utils::INPUT_GET)) {
@@ -104,6 +104,13 @@ if (isset($a_headers) && count($a_headers)) {
if ($search_request) {
$OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $count));
}
+
+ // remember last HIGHESTMODSEQ value (if supported)
+ // we need it for flag updates in check-recent
+ $data = $RCMAIL->storage->folder_data($mbox_name);
+ if (!empty($data['HIGHESTMODSEQ'])) {
+ $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ'];
+ }
}
else {
// handle IMAP errors (e.g. #1486905)
diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc
index 03d6de326..210bedbb8 100644
--- a/program/steps/mail/search.inc
+++ b/program/steps/mail/search.inc
@@ -131,6 +131,13 @@ if (!empty($result_h)) {
rcmail_js_message_list($result_h);
if ($search_str)
$OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $RCMAIL->storage->count(NULL, 'ALL')));
+
+ // remember last HIGHESTMODSEQ value (if supported)
+ // we need it for flag updates in check-recent
+ $data = $RCMAIL->storage->folder_data($mbox_name);
+ if (!empty($data['HIGHESTMODSEQ'])) {
+ $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ'];
+ }
}
// handle IMAP errors (e.g. #1486905)
else if ($err_code = $RCMAIL->storage->get_error_code()) {