Changeset 3612 in subversion


Ignore:
Timestamp:
May 12, 2010 3:09:29 PM (3 years ago)
Author:
alec
Message:
  • Fix check-recent action issues and performance (#1486526)
  • Fix messages order after checking for recent (#1484664)
  • Fix messages copying
  • Reset check-recent interval after check-recent by hand
Location:
trunk/roundcubemail
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r3608 r3612  
    22=========================== 
    33 
     4- Fix check-recent action issues and performance (#1486526) 
     5- Fix messages order after checking for recent (#1484664) 
    46- Fix autocomplete shows entries without email (#1486452) 
    57- Fix listupdate event doesn't trigger on search response (#1486708) 
  • trunk/roundcubemail/program/include/rcube_imap.php

    r3586 r3612  
    413413     * @param  string  Mode for count [ALL|THREADS|UNSEEN|RECENT] 
    414414     * @param  boolean Force reading from server and update cache 
    415      * @param  boolean Enables MAXUIDs checking 
     415     * @param  boolean Enables storing folder status info (max UID/count), 
     416     *                 required for mailbox_status() 
    416417     * @return int     Number of messages 
    417418     * @access public 
    418419     */ 
    419     function messagecount($mbox_name='', $mode='ALL', $force=false, $maxuid=true) 
     420    function messagecount($mbox_name='', $mode='ALL', $force=false, $status=true) 
    420421    { 
    421422        $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox; 
    422         return $this->_messagecount($mailbox, $mode, $force, $maxuid); 
     423        return $this->_messagecount($mailbox, $mode, $force, $status); 
    423424    } 
    424425 
     
    430431     * @see     rcube_imap::messagecount() 
    431432     */ 
    432     private function _messagecount($mailbox='', $mode='ALL', $force=false, $maxuid=true) 
     433    private function _messagecount($mailbox='', $mode='ALL', $force=false, $status=true) 
    433434    { 
    434435        $mode = strtoupper($mode); 
     
    456457        if ($mode == 'THREADS') { 
    457458            $count = $this->_threadcount($mailbox, $msg_count); 
    458             if ($maxuid) 
    459                 $_SESSION['maxuid'][$mailbox] = $msg_count ? $this->_id2uid($msg_count, $mailbox) : 0; 
     459            if ($status) { 
     460                $this->set_folder_stats($mailbox, 'cnt', $msg_count); 
     461                $this->set_folder_stats($mailbox, 'maxuid', $msg_count ? $this->_id2uid($msg_count, $mailbox) : 0); 
     462            } 
    460463        } 
    461464        // RECENT count is fetched a bit different 
     
    481484            $count = is_array($index) ? count($index) : 0; 
    482485 
    483             if ($mode == 'ALL' && $maxuid) 
    484                 $_SESSION['maxuid'][$mailbox] = $index ? $this->_id2uid(max($index), $mailbox) : 0; 
     486            if ($mode == 'ALL' && $status) { 
     487                $this->set_folder_stats($mailbox, 'cnt', $count); 
     488                $this->set_folder_stats($mailbox, 'maxuid', $index ? $this->_id2uid(max($index), $mailbox) : 0); 
     489            } 
    485490        } 
    486491        else { 
     
    489494            else { 
    490495                $count = $this->conn->countMessages($mailbox); 
    491                 if ($maxuid) 
    492                     $_SESSION['maxuid'][$mailbox] = $count ? $this->_id2uid($count, $mailbox) : 0; 
     496                if ($status) { 
     497                    $this->set_folder_stats($mailbox,'cnt', $count); 
     498                    $this->set_folder_stats($mailbox, 'maxuid', $count ? $this->_id2uid($count, $mailbox) : 0); 
     499                } 
    493500            } 
    494501        } 
     
    10341041    } 
    10351042   
    1036     /** 
    1037      * Fetches IDS of pseudo recent messages. 
     1043 
     1044    /** 
     1045     * Returns current status of mailbox 
    10381046     * 
    10391047     * We compare the maximum UID to determine the number of 
    10401048     * new messages because the RECENT flag is not reliable. 
    10411049     * 
    1042      * @param string  Mailbox/folder name 
    1043      * @return array  List of recent message UIDs 
    1044      */ 
    1045     function recent_uids($mbox_name = null, $nofetch = false) 
     1050     * @param string Mailbox/folder name 
     1051     * @return int   Folder status 
     1052     */ 
     1053    function mailbox_status($mbox_name = null) 
    10461054    { 
    10471055        $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox; 
    1048         $old_maxuid = intval($_SESSION['maxuid'][$mailbox]); 
    1049      
    1050         // refresh message count -> will update $_SESSION['maxuid'][$mailbox] 
     1056        $old = $this->get_folder_stats($mailbox); 
     1057 
     1058        // refresh message count -> will update  
    10511059        $this->_messagecount($mailbox, 'ALL', true); 
    1052      
    1053         if ($_SESSION['maxuid'][$mailbox] > $old_maxuid) { 
    1054             $maxuid = max(1, $old_maxuid+1); 
    1055             return array_values((array)$this->conn->fetchHeaderIndex( 
    1056                 $mailbox, "$maxuid:*", 'UID', $this->skip_deleted, true)); 
    1057         } 
    1058      
    1059         return array(); 
    1060     } 
    1061    
     1060 
     1061        $result = 0; 
     1062        $new = $this->get_folder_stats($mailbox); 
     1063 
     1064        // got new messages 
     1065        if ($new['maxuid'] > $old['maxuid']) 
     1066            $result += 1; 
     1067        // some messages has been deleted 
     1068        if ($new['cnt'] < $old['cnt']) 
     1069            $result += 2; 
     1070 
     1071        // @TODO: optional checking for messages flags changes (?) 
     1072        // @TODO: UIDVALIDITY checking 
     1073 
     1074        return $result; 
     1075    } 
     1076 
     1077 
     1078    /** 
     1079     * Stores folder statistic data in session 
     1080     * @TODO: move to separate DB table (cache?) 
     1081     * 
     1082     * @param string Mailbox name 
     1083     * @param string Data name 
     1084     * @param mixed  Data value 
     1085     */ 
     1086    private function set_folder_stats($mbox_name, $name, $data) 
     1087    { 
     1088        $_SESSION['folders'][$mbox_name][$name] = $data; 
     1089    } 
     1090 
     1091 
     1092    /** 
     1093     * Gets folder statistic data 
     1094     * 
     1095     * @param string Mailbox name 
     1096     * @return array Stats data 
     1097     */ 
     1098    private function get_folder_stats($mbox_name) 
     1099    { 
     1100        if ($_SESSION['folders'][$mbox_name]) 
     1101            return (array) $_SESSION['folders'][$mbox_name]; 
     1102        else 
     1103            return array(); 
     1104    } 
     1105 
     1106 
    10621107    /** 
    10631108     * Return sorted array of message IDs (not UIDs) 
     
    15391584        if (!empty($this->search_string)) 
    15401585            $this->search_set = $this->search('', $this->search_string, $this->search_charset, 
    1541  
    1542         $this->search_sort_field, $this->search_threads); 
    1543        
     1586                $this->search_sort_field, $this->search_threads); 
     1587 
    15441588        return $this->get_search_set(); 
    15451589    } 
  • trunk/roundcubemail/program/js/app.js

    r3611 r3612  
    14051405 
    14061406    // reset all-pages-selection 
    1407     if (selected || list.selection.length != list.rowcount) 
     1407    if (selected || (list.selection.length && list.selection.length != list.rowcount)) 
    14081408      this.select_all_mode = false; 
    14091409 
     
    15631563      depth: flags.depth?flags.depth:0, 
    15641564      unread_children: flags.unread_children, 
    1565       parent_uid: flags.parent_uid 
     1565      parent_uid: flags.parent_uid, 
     1566      selected: this.select_all_mode || this.message_list.in_selection(uid) 
    15661567    }); 
    15671568 
    15681569    var c, tree = expando = '', 
    1569       rows = this.message_list.rows, 
     1570      list = this.message_list, 
     1571      rows = list.rows, 
    15701572      rowcount = tbody.rows.length, 
    15711573      even = rowcount%2, 
     
    15771579        + (flags.flagged ? ' flagged' : '') 
    15781580        + (flags.unread_children && !flags.unread && !this.env.autoexpand_threads ? ' unroot' : '') 
    1579         + (this.message_list.in_selection(uid) ? ' selected' : ''), 
     1581        + (message.selected ? ' selected' : ''), 
    15801582      // for performance use DOM instead of jQuery here 
    15811583      row = document.createElement('tr'), 
     
    16021604      icon = this.env.unreadicon; 
    16031605 
     1606    // update selection 
     1607    if (message.selected && !list.in_selection(uid)) 
     1608      list.selection.push(uid); 
     1609 
    16041610    // threads 
    16051611    if (this.env.threading) { 
     
    16071613      var width = message.depth * 15; 
    16081614      if (message.depth) { 
    1609         if ((this.env.autoexpand_threads == 0 || this.env.autoexpand_threads == 2) && 
    1610             (!rows[message.parent_uid] || !rows[message.parent_uid].expanded)) { 
     1615        if ((rows[message.parent_uid] && rows[message.parent_uid].expanded === false) 
     1616          || ((this.env.autoexpand_threads == 0 || this.env.autoexpand_threads == 2) && 
     1617            (!rows[message.parent_uid] || !rows[message.parent_uid].expanded)) 
     1618        ) { 
    16111619          row.style.display = 'none'; 
    16121620          message.expanded = false; 
     
    16141622        else 
    16151623          message.expanded = true; 
    1616         } 
     1624      } 
    16171625      else if (message.has_children) { 
    16181626        if (typeof(message.expanded) == 'undefined' && (this.env.autoexpand_threads == 1 || (this.env.autoexpand_threads == 2 && message.unread_children))) { 
     
    16681676    } 
    16691677 
    1670     this.message_list.insert_row(row, attop); 
     1678    list.insert_row(row, attop); 
    16711679 
    16721680    // remove 'old' row 
    1673     if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize) { 
    1674       var uid = this.message_list.get_last_row(); 
    1675       this.message_list.remove_row(uid); 
    1676       this.message_list.clear_selection(uid); 
     1681    if (attop && this.env.pagesize && list.rowcount > this.env.pagesize) { 
     1682      var uid = list.get_last_row(); 
     1683      list.remove_row(uid); 
     1684      list.clear_selection(uid); 
    16771685    } 
    16781686  }; 
     
    18601868 
    18611869    // set page=1 if changeing to another mailbox 
    1862     if (!page && this.env.mailbox != mbox) { 
     1870    if (this.env.mailbox != mbox) { 
    18631871      page = 1; 
    18641872      this.env.current_page = page; 
     1873      this.select_all_mode = false; 
    18651874      this.show_contentframe(false); 
    18661875    } 
     
    18731882    if (this.message_list) { 
    18741883      this.message_list.clear_selection(); 
    1875       this.select_all_mode = false; 
    18761884    } 
    18771885    this.select_folder(mbox, this.env.mailbox); 
     
    19071915    this.http_request('list', url+add_url, true); 
    19081916  }; 
     1917 
     1918  // removes messages that doesn't exists from list selection array 
     1919  this.update_selection = function() 
     1920  { 
     1921    var selected = this.message_list.selection, 
     1922      rows = this.message_list.rows, 
     1923      i, selection = []; 
     1924 
     1925    for (i in selected) 
     1926      if (rows[selected[i]]) 
     1927        selection.push(selected[i]); 
     1928 
     1929    this.message_list.selection = selection; 
     1930  } 
    19091931 
    19101932  // expand all threads with unread children 
     
    21772199  this.copy_messages = function(mbox) 
    21782200  { 
     2201    if (mbox && typeof mbox == 'object') 
     2202      mbox = mbox.id; 
     2203 
    21792204    // exit if current or no mailbox specified or if selection is empty 
    21802205    if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))) 
     
    48704895  }; 
    48714896 
    4872   // use an image to send a keep-alive siganl to the server 
    4873   this.send_keep_alive = function() 
    4874   { 
    4875     var d = new Date(); 
    4876     this.http_request('keep-alive', '_t='+d.getTime()); 
    4877   }; 
    4878  
    4879   // start interval for keep-alive/recent_check signal 
     4897  // starts interval for keep-alive/check-recent signal 
    48804898  this.start_keepalive = function() 
    48814899  { 
     4900    if (this._int) 
     4901      clearInterval(this._int); 
     4902 
    48824903    if (this.env.keep_alive && !this.env.framed && this.task=='mail' && this.gui_objects.mailboxlist) 
    48834904      this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000); 
     
    48864907  }; 
    48874908 
    4888   // send periodic request to check for recent messages 
     4909  // sends keep-alive signal to the server 
     4910  this.send_keep_alive = function() 
     4911  { 
     4912    var d = new Date(); 
     4913    this.http_request('keep-alive', '_t='+d.getTime()); 
     4914  }; 
     4915 
     4916  // sends request to check for recent messages 
    48894917  this.check_for_recent = function(refresh) 
    48904918  { 
     
    48974925      this.set_busy(true, 'checkingmail'); 
    48984926      addurl += '&_refresh=1'; 
     4927      // reset check-recent interval 
     4928      this.start_keepalive(); 
    48994929    } 
    49004930 
  • trunk/roundcubemail/program/steps/mail/check_recent.inc

    r3367 r3612  
    2020*/ 
    2121 
    22 $a_mailboxes = $IMAP->list_mailboxes(); 
     22$current = $IMAP->get_mailbox_name(); 
    2323$check_all = !empty($_GET['_refresh']) || (bool)$RCMAIL->config->get('check_all_folders'); 
     24$a_mailboxes = $check_all ? $IMAP->list_mailboxes() : (array)$current; 
    2425 
    2526// check recent/unseen counts for all mailboxes 
    2627foreach ($a_mailboxes as $mbox_name) { 
    27   if ($mbox_name == $IMAP->get_mailbox_name()) { 
    28     if ($recents = $IMAP->recent_uids($mbox_name)) { 
    29       // refresh saved search set 
    30       if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && isset($_SESSION['search'][$search_request])) { 
    31         $_SESSION['search'][$search_request] = $IMAP->refresh_search(); 
    32       } 
    33        
    34       // get overall message count; allow caching because rcube_imap::recent_uids() did a refresh 
    35       $all_count = $IMAP->messagecount(NULL, $IMAP->threading ? 'THREADS' : 'ALL'); 
    36        
    37       $unread_count = $IMAP->messagecount(NULL, 'UNSEEN', TRUE); 
    38       $_SESSION['unseen_count'][$mbox_name] = $unread_count; 
     28    if ($mbox_name == $current && ($status = $IMAP->mailbox_status($mbox_name))) { 
    3929 
    40       $OUTPUT->set_env('messagecount', $all_count); 
    41       $OUTPUT->set_env('pagecount', ceil($all_count/$IMAP->page_size)); 
    42       $OUTPUT->command('set_unread_count', $mbox_name, $unread_count, ($mbox_name == 'INBOX')); 
    43       $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($all_count)); 
     30        rcmail_send_unread_count($mbox_name, true); 
    4431 
    45       if ($RCMAIL->config->get('focus_on_new_message',true)) 
    46         $OUTPUT->command('new_message_focus'); 
     32        // refresh saved search set 
     33        $search_request = get_input_value('_search', RCUBE_INPUT_GPC); 
     34        if ($search_request && isset($_SESSION['search'][$search_request])) { 
     35            $_SESSION['search'][$search_request] = $IMAP->refresh_search(); 
     36        } 
    4737 
    48       if (!empty($_GET['_quota'])) 
    49         $OUTPUT->command('set_quota', rcmail_quota_content()); 
     38        if (!empty($_GET['_quota'])) 
     39            $OUTPUT->command('set_quota', rcmail_quota_content()); 
    5040 
    51       // trigger plugin hook 
    52       $RCMAIL->plugins->exec_hook('new_messages', array('mailbox' => $mbox_name, 'count' => count($recents))); 
     41        // "No-list" mode, don't get messages 
     42        if (empty($_GET['_list'])) 
     43            continue; 
    5344 
    54       // "No-list" mode, don't get messages 
    55       if (empty($_GET['_list'])) 
    56         continue; 
     45        // get overall message count; allow caching because rcube_imap::mailbox_status() did a refresh 
     46        $all_count = $IMAP->messagecount(null, $IMAP->threading ? 'THREADS' : 'ALL'); 
    5747 
    58       if ($IMAP->threading) { 
    59         $OUTPUT->command('message_list.clear'); 
    60         $sort_col   = isset($_SESSION['sort_col'])   ? $_SESSION['sort_col']   : $CONFIG['message_sort_col']; 
    61         $sort_order = isset($_SESSION['sort_order']) ? $_SESSION['sort_order'] : $CONFIG['message_sort_order']; 
    62         $result_h = $IMAP->list_headers($mbox_name, NULL, $sort_col, $sort_order); 
    63         // add to the list 
    64         rcmail_js_message_list($result_h); 
    65       } 
    66       else { 
    67         // use SEARCH/SORT to find recent messages 
    68         $search_str = 'UID '.min($recents).':'.max($recents); 
    69         if ($search_request) 
    70           $search_str .= ' '.$IMAP->search_string; 
     48        // check current page if we're not on the first page 
     49        if ($all_count && $IMAP->list_page > 1) { 
     50            $remaining = $all_count - $IMAP->page_size * ($IMAP->list_page - 1); 
     51            if ($remaining <= 0) { 
     52                $IMAP->set_page($IMAP->list_page-1); 
     53                $_SESSION['page'] = $IMAP->list_page; 
     54            } 
     55        } 
    7156 
    72         if ($IMAP->search($mbox_name, $search_str, NULL, 'date')) { 
    73           // revert sort order 
    74           $order = $_SESSION['sort_col'] == 'date' && $_SESSION['sort_order'] == 'DESC' ? 'ASC' : 'DESC'; 
    75           // get the headers and add them to the list 
    76           $result_h = $IMAP->list_headers($mbox_name, 1, 'date', $order); 
    77           rcmail_js_message_list($result_h, true, false); 
     57        $OUTPUT->set_env('messagecount', $all_count); 
     58        $OUTPUT->set_env('pagecount', ceil($all_count/$IMAP->page_size)); 
     59        $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($all_count)); 
     60        $OUTPUT->set_env('current_page', $all_count ? $IMAP->list_page : 1); 
     61 
     62        if ($status & 1) { 
     63            if ($RCMAIL->config->get('focus_on_new_message', true)) 
     64                $OUTPUT->command('new_message_focus'); 
     65            // trigger plugin hook 
     66            $RCMAIL->plugins->exec_hook('new_messages', array('mailbox' => $mbox_name)); 
    7867        } 
    79       } 
     68 
     69        // remove old rows (and clear selection if new list is empty) 
     70        $OUTPUT->command('message_list.clear', $all_count ? false : true); 
     71 
     72        if ($all_count) { 
     73            $a_headers = $IMAP->list_headers($mbox_name, null, $_SESSION['sort_col'], $_SESSION['sort_order']); 
     74            // add message rows 
     75            rcmail_js_message_list($a_headers, false, false); 
     76            // remove messages that don't exists from list selection array 
     77            $OUTPUT->command('update_selection'); 
     78        } 
    8079    } 
    8180    else { 
    82       rcmail_send_unread_count($mbox_name, true); 
     81        rcmail_send_unread_count($mbox_name, true); 
    8382    } 
    84   } 
    85   else if ($check_all) { 
    86     rcmail_send_unread_count($mbox_name, true); 
    87   } 
    8883} 
    8984 
Note: See TracChangeset for help on using the changeset viewer.