From: Michael M Slusarz Date: Thu, 24 Dec 2009 09:04:30 +0000 (-0700) Subject: If selected message(s) disappear from mailbox, gracefully handle in the UI X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=7b8ddd0c8667d890fbef894ed6d517bbfcd983b6;p=horde.git If selected message(s) disappear from mailbox, gracefully handle in the UI This is a very subtle yet important issue. Goes together with Request #7297 in that messages that may disappear from the search mailbox (e.g. read messages in the Virtual Inbox) correctly causes all selected message functions to be disabled and the preview pane to clear. --- diff --git a/imp/docs/CHANGES b/imp/docs/CHANGES index 05fb122ae..dddc68095 100644 --- a/imp/docs/CHANGES +++ b/imp/docs/CHANGES @@ -2,7 +2,10 @@ v5.0-git -------- -[mms] Only update search mailbox on explicit user action (Request #7297). +[mms] If selected message(s) disappear from mailbox, gracefully handle in the + user interface (DIMP). +[mms] Only update search mailbox on explicit user action (Request #7297) + (DIMP). [mms] Add auto-save draft to IMP (Request #7656). [mms] Add keyboard shortcut to move to next unseen message (Request #8223). [mms] Add hook to dynamically change mailbox label (Request #6734). diff --git a/imp/js/ViewPort.js b/imp/js/ViewPort.js index 9ee91dfff..3b1bd62d8 100644 --- a/imp/js/ViewPort.js +++ b/imp/js/ViewPort.js @@ -171,6 +171,9 @@ * the viewable rows. Keys are a unique ID (see also the 'rowlist' * entry). Values are the data objects. Internal keys for these data * objects must NOT begin with the string 'VP_'. + * disappear: (array) If update is set, this is the list of unique IDs that + * have been cached by the browser but no longer appear on the + * server. * label: (string) [REQUIRED when initial is true] The label to use for the * view. * metadata [optional]: (object) Metadata for the view. Entries in buffer are @@ -828,6 +831,9 @@ var ViewPort = Class.create({ if (r.reset) { this.select(new ViewPort_Selection()); + } else if (r.update && r.disappear && r.disappear.size()) { + this.deselect(this.createSelection('uid', r.disappear, r.view)); + buffer.removeData(r.disappear); } llist.unset(r.requestid); @@ -1576,6 +1582,14 @@ ViewPort_Buffer = Class.create({ }, this); }, + removeData: function(uids) + { + uids.each(function(u) { + this.data.unset(u); + this.uidlist.unset(u); + }, this); + }, + resetRowlist: function() { this.rowlist = $H(); diff --git a/imp/lib/Views/ListMessages.php b/imp/lib/Views/ListMessages.php index 7799d2e69..e407e60e6 100644 --- a/imp/lib/Views/ListMessages.php +++ b/imp/lib/Views/ListMessages.php @@ -230,21 +230,37 @@ class IMP_Views_ListMessages /* Generate the message list and the UID -> rownumber list. */ $data = $msglist = $rowlist = array(); - foreach (range($slice_start, $slice_end) as $key) { - $uid = $sorted_list['s'][$key] . - (isset($sorted_list['m'][$key]) - ? IMP::IDX_SEP . $sorted_list['m'][$key] - : ''); - if ($uid) { - $msglist[$key] = $sorted_list['s'][$key]; - $rowlist[$uid] = $key; - if (!isset($cached[$uid])) { - $data[] = $key; - } + $uidlist = $this->_getUidList($slice_start, $slice_end, $sorted_list); + foreach ($uidlist as $uid => $seq) { + $msglist[$seq] = $sorted_list['s'][$seq]; + $rowlist[$uid] = $seq; + if (!isset($cached[$uid])) { + $data[] = $seq; } } $result->rowlist = $rowlist; + /* If we are updating the rowlist on the browser, and we have cached + * browser data information, we need to send a list of messages that + * have 'disappeared'. */ + if (isset($result->update)) { + if (($slice_start != 0) && + ($slice_end != count($sorted_list['s']))) { + $uidlist = $this->_getUidList(0, count($sorted_list['s']), $sorted_list); + } + + $disappear = array(); + foreach (array_keys($cached) as $val) { + if (!isset($uidlist[$val])) { + $disappear[] = $val; + } + } + + if (!empty($disappear)) { + $result->disappear = $disappear; + } + } + /* Build the list for rangeslice information. */ if ($args['rangeslice']) { $slice = new stdClass; @@ -278,6 +294,32 @@ class IMP_Views_ListMessages } /** + * Generates the list of unique UIDs for the current mailbox. + * + * @param integer $start The slice start. + * @param integer $end The slice end. + * @param array $sorted_list The sorted list array. + * + * @param array UIDs as the keys, and sequence numbers as the values. + */ + protected function _getUidList($start, $end, $sorted_list) + { + $ret = array(); + + for ($i = $start; $i <= $end; ++$i) { + $uid = $sorted_list['s'][$i] . + (isset($sorted_list['m'][$i]) + ? IMP::IDX_SEP . $sorted_list['m'][$i] + : ''); + if ($uid) { + $ret[$uid] = $i; + } + } + + return $ret; + } + + /** * Obtains IMAP overview data for a given set of message UIDs. * * @param IMP_Mailbox $imp_mailbox An IMP_Mailbox:: object.