Aleksander Machniak
2013-12-23 ac0fc383fd43e8955b0ab22f70463159b14c74b0
Fix so message flags modified by another client are applied on the list on refresh (#1485186)
7 files modified
99 ■■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/js/app.js 19 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_imap.php 35 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_storage.php 12 ●●●●● patch | view | raw | blame | history
program/steps/mail/check_recent.inc 18 ●●●●● patch | view | raw | blame | history
program/steps/mail/list.inc 7 ●●●●● patch | view | raw | blame | history
program/steps/mail/search.inc 7 ●●●●● patch | view | raw | blame | history
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)
program/js/app.js
@@ -6923,6 +6923,16 @@
      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 @@
    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;
  };
program/lib/Roundcube/rcube_imap.php
@@ -680,6 +680,41 @@
    /**
     * 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
program/lib/Roundcube/rcube_storage.php
@@ -360,6 +360,18 @@
    /**
     * 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
program/steps/mail/check_recent.inc
@@ -114,6 +114,24 @@
            $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
program/steps/mail/list.inc
@@ -103,6 +103,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 {
program/steps/mail/search.inc
@@ -131,6 +131,13 @@
  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()) {