[geary/wip/713190-resort-2] More explicit sorting of emails and conversations



commit 59c2a6ab960cc068e52ba11e19fc26f9edb54338
Author: Jim Nelson <jim yorba org>
Date:   Wed Jan 21 14:39:33 2015 -0800

    More explicit sorting of emails and conversations
    
    Now distinguishes between sorting email/conversations by date sent
    (the Date: header) and date received (IMAP's INTERNALDATE).

 src/client/application/geary-controller.vala       |   23 ++--
 .../conversation-list/conversation-list-store.vala |   19 +++-
 .../formatted-conversation-data.vala               |    4 +-
 .../conversation-viewer/conversation-viewer.vala   |   11 ++-
 src/client/util/util-email.vala                    |    6 +-
 src/engine/api/geary-email.vala                    |   85 +++++++++------
 src/engine/app/app-conversation.vala               |  119 ++++++++++++--------
 .../imap-engine/imap-engine-email-prefetcher.vala  |    4 +-
 8 files changed, 167 insertions(+), 104 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 27affab..d451af3 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -1421,7 +1421,7 @@ public class GearyController : Geary.BaseObject {
             return;
         
         // TODO: Determine how to map between conversations and drafts correctly.
-        on_edit_draft(activated.get_latest_email(Geary.App.Conversation.Location.IN_FOLDER));
+        on_edit_draft(activated.get_latest_recv_email(Geary.App.Conversation.Location.IN_FOLDER));
     }
     
     private void on_edit_draft(Geary.Email draft) {
@@ -1646,11 +1646,13 @@ public class GearyController : Geary.BaseObject {
         dialog.run();
     }
     
+    // latest_sent_only uses Email's Date: field, which corresponds to how they're sorted in the
+    // ConversationViewer
     private Gee.ArrayList<Geary.EmailIdentifier> get_conversation_email_ids(
-        Geary.App.Conversation conversation, bool latest_only,
+        Geary.App.Conversation conversation, bool latest_sent_only,
         Gee.ArrayList<Geary.EmailIdentifier> add_to) {
-        if (latest_only) {
-            Geary.Email? latest = conversation.get_latest_email(
+        if (latest_sent_only) {
+            Geary.Email? latest = conversation.get_latest_sent_email(
                 Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
             if (latest != null)
                 add_to.add(latest.id);
@@ -1662,20 +1664,19 @@ public class GearyController : Geary.BaseObject {
     }
     
     private Gee.Collection<Geary.EmailIdentifier> get_conversation_collection_email_ids(
-        Gee.Collection<Geary.App.Conversation> conversations, bool latest_only = false) {
+        Gee.Collection<Geary.App.Conversation> conversations, bool latest_sent_only) {
         Gee.ArrayList<Geary.EmailIdentifier> ret = new Gee.ArrayList<Geary.EmailIdentifier>();
         
         foreach(Geary.App.Conversation c in conversations)
-            get_conversation_email_ids(c, latest_only, ret);
+            get_conversation_email_ids(c, latest_sent_only, ret);
         
         return ret;
     }
     
-    private Gee.ArrayList<Geary.EmailIdentifier> get_selected_email_ids(
-        bool latest_only) {
+    private Gee.ArrayList<Geary.EmailIdentifier> get_selected_email_ids(bool latest_sent_only) {
         Gee.ArrayList<Geary.EmailIdentifier> ids = new Gee.ArrayList<Geary.EmailIdentifier>();
         foreach (Geary.App.Conversation conversation in selected_conversations)
-            get_conversation_email_ids(conversation, latest_only, ids);
+            get_conversation_email_ids(conversation, latest_sent_only, ids);
         return ids;
     }
     
@@ -1698,7 +1699,9 @@ public class GearyController : Geary.BaseObject {
             
             // Only check the messages that "Mark as Unread" would mark, so we
             // don't add the menu option and have it not do anything.
-            Geary.Email? latest = conversation.get_latest_email(
+            //
+            // Sort by Date: field to correspond with ConversationViewer ordering
+            Geary.Email? latest = conversation.get_latest_sent_email(
                 Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
             if (latest != null && latest.email_flags != null
                 && !latest.email_flags.contains(Geary.EmailFlags.UNREAD))
diff --git a/src/client/conversation-list/conversation-list-store.vala 
b/src/client/conversation-list/conversation-list-store.vala
index 2444f7c..8f20f0c 100644
--- a/src/client/conversation-list/conversation-list-store.vala
+++ b/src/client/conversation-list/conversation-list-store.vala
@@ -3,7 +3,16 @@
  * This software is licensed under the GNU Lesser General Public License
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
- 
+
+/**
+ * A Gtk.ListStore of sorted { link Geary.App.Conversation}s.
+ *
+ * Conversations are sorted by { link Geary.EmailProperties.date_received} (IMAP's INTERNALDATE)
+ * rather than the Date: header, as that ensures newly received email sort to the top where the
+ * user expects to see them.  The ConversationViewer sorts by the Date: header, as that presents
+ * better to the user.
+ */
+
 public class ConversationListStore : Gtk.ListStore {
     public const Geary.Email.Field REQUIRED_FIELDS =
         Geary.Email.Field.ENVELOPE | Geary.Email.Field.FLAGS | Geary.Email.Field.PROPERTIES;
@@ -198,7 +207,7 @@ public class ConversationListStore : Gtk.ListStore {
         foreach (Geary.App.Conversation conversation in sorted_conversations) {
             // find oldest unread message for the preview
             Geary.Email? need_preview = null;
-            foreach (Geary.Email email in 
conversation.get_emails(Geary.App.Conversation.Ordering.DATE_ASCENDING)) {
+            foreach (Geary.Email email in 
conversation.get_emails(Geary.App.Conversation.Ordering.RECV_DATE_ASCENDING)) {
                 if (email.email_flags.is_unread()) {
                     need_preview = email;
                     
@@ -209,7 +218,7 @@ public class ConversationListStore : Gtk.ListStore {
             // if all are read, use newest in-folder message, then newest out-of-folder if not
             // present
             if (need_preview == null) {
-                need_preview = 
conversation.get_latest_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
+                need_preview = 
conversation.get_latest_recv_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
                 if (need_preview == null)
                     continue;
             }
@@ -265,7 +274,7 @@ public class ConversationListStore : Gtk.ListStore {
             return;
         }
         
-        Geary.Email? last_email = conversation.get_latest_email(Geary.App.Conversation.Location.ANYWHERE);
+        Geary.Email? last_email = 
conversation.get_latest_recv_email(Geary.App.Conversation.Location.ANYWHERE);
         if (last_email == null) {
             debug("Cannot refresh conversation: last email is null");
             
@@ -347,7 +356,7 @@ public class ConversationListStore : Gtk.ListStore {
     }
     
     private bool add_conversation(Geary.App.Conversation conversation) {
-        Geary.Email? last_email = conversation.get_latest_email(Geary.App.Conversation.Location.ANYWHERE);
+        Geary.Email? last_email = 
conversation.get_latest_recv_email(Geary.App.Conversation.Location.ANYWHERE);
         if (last_email == null) {
             debug("Cannot add conversation: last email is null");
             
diff --git a/src/client/conversation-list/formatted-conversation-data.vala 
b/src/client/conversation-list/formatted-conversation-data.vala
index 65e02ae..211361a 100644
--- a/src/client/conversation-list/formatted-conversation-data.vala
+++ b/src/client/conversation-list/formatted-conversation-data.vala
@@ -116,7 +116,7 @@ public class FormattedConversationData : Geary.BaseObject {
     
     public bool update_date_string() {
         // get latest email *in folder* for the conversation's date, fall back on out-of-folder
-        Geary.Email? latest = 
conversation.get_latest_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
+        Geary.Email? latest = 
conversation.get_latest_recv_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
         if (latest == null || latest.properties == null)
             return false;
         
@@ -181,7 +181,7 @@ public class FormattedConversationData : Geary.BaseObject {
         // Build chronological list of AuthorDisplay records, setting to unread if any message by
         // that author is unread
         Gee.ArrayList<ParticipantDisplay> list = new Gee.ArrayList<ParticipantDisplay>();
-        foreach (Geary.Email message in 
conversation.get_emails(Geary.App.Conversation.Ordering.DATE_ASCENDING)) {
+        foreach (Geary.Email message in 
conversation.get_emails(Geary.App.Conversation.Ordering.RECV_DATE_ASCENDING)) {
             // only display if something to display
             Geary.RFC822.MailboxAddresses? addresses = use_to ? message.to : message.from;
             if (addresses == null || addresses.size < 1)
diff --git a/src/client/conversation-viewer/conversation-viewer.vala 
b/src/client/conversation-viewer/conversation-viewer.vala
index 2704986..8b0df4d 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -4,6 +4,13 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
+/**
+ * A WebKit view displaying all the emails in a { link Geary.App.Conversation}.
+ *
+ * Unlike ConversationListStore (which sorts by date received), ConversationViewer sorts by the
+ * { link Geary.Email.date} field (the Date: header), as that's the date displayed to the user.
+ */
+
 public class ConversationViewer : Gtk.Box {
     public const Geary.Email.Field REQUIRED_FIELDS =
         Geary.Email.Field.HEADER
@@ -129,7 +136,7 @@ public class ConversationViewer : Gtk.Box {
     
     // List of emails in this view.
     public Gee.TreeSet<Geary.Email> messages { get; private set; default = 
-        new Gee.TreeSet<Geary.Email>(Geary.Email.compare_date_ascending); }
+        new Gee.TreeSet<Geary.Email>(Geary.Email.compare_sent_date_ascending); }
     
     // The HTML viewer to view the emails.
     public ConversationWebView web_view { get; private set; }
@@ -493,7 +500,7 @@ public class ConversationViewer : Gtk.Box {
         // Fetch full messages.
         Gee.Collection<Geary.Email>? messages_to_add
             = yield list_full_messages_async(conversation.get_emails(
-            Geary.App.Conversation.Ordering.DATE_ASCENDING), cancellable);
+            Geary.App.Conversation.Ordering.SENT_DATE_ASCENDING), cancellable);
         
         // Add messages.
         if (messages_to_add != null) {
diff --git a/src/client/util/util-email.vala b/src/client/util/util-email.vala
index 1f0c66f..464888f 100644
--- a/src/client/util/util-email.vala
+++ b/src/client/util/util-email.vala
@@ -5,8 +5,8 @@
  */
 
 public int compare_conversation_ascending(Geary.App.Conversation a, Geary.App.Conversation b) {
-    Geary.Email? a_latest = a.get_latest_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
-    Geary.Email? b_latest = b.get_latest_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
+    Geary.Email? a_latest = a.get_latest_recv_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
+    Geary.Email? b_latest = b.get_latest_recv_email(Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
     
     if (a_latest == null)
         return (b_latest == null) ? 0 : -1;
@@ -15,7 +15,7 @@ public int compare_conversation_ascending(Geary.App.Conversation a, Geary.App.Co
     
     // use date-received so newly-arrived messages float to the top, even if they're send date
     // was earlier (think of mailing lists that batch up forwarded mail)
-    return a_latest.properties.date_received.compare(b_latest.properties.date_received);
+    return Geary.Email.compare_recv_date_ascending(a_latest, b_latest);
 }
 
 public int compare_conversation_descending(Geary.App.Conversation a, Geary.App.Conversation b) {
diff --git a/src/engine/api/geary-email.vala b/src/engine/api/geary-email.vala
index 6100252..26ab8ae 100644
--- a/src/engine/api/geary-email.vala
+++ b/src/engine/api/geary-email.vala
@@ -361,24 +361,61 @@ public class Geary.Email : BaseObject {
     }
     
     /**
-     * CompareFunc to sort Email by date.  If the date field is not available on both Emails, their
-     * identifiers are compared.
+     * CompareFunc to sort { link Email} by { link date} ascending.
+     *
+     * If the date field is unavailable on either Email, their identifiers are compared to
+     * stabilize the sort.
      */
-    public static int compare_date_ascending(Geary.Email aemail, Geary.Email bemail) {
-        int diff = 0;
-        if (aemail.date != null && bemail.date != null)
-            diff = aemail.date.value.compare(bemail.date.value);
+    public static int compare_sent_date_ascending(Geary.Email aemail, Geary.Email bemail) {
+        if (aemail.date == null || bemail.date == null) {
+            GLib.message("Warning: comparing email for sent date but no Date: field loaded");
+            
+            return compare_id_ascending(aemail, bemail);
+        }
+        
+        int compare = aemail.date.value.compare(bemail.date.value);
         
         // stabilize sort by using the mail identifier's stable sort ordering
-        return (diff != 0) ? diff : compare_id_ascending(aemail, bemail);
+        return (compare != 0) ? compare : compare_id_ascending(aemail, bemail);
     }
     
     /**
-     * CompareFunc to sort Email by date.  If the date field is not available on both Emails, their
-     * identifiers are compared.
+     * CompareFunc to sort { link Email} by { link date} descending.
+     *
+     * If the date field is unavailable on either Email, their identifiers are compared to
+     * stabilize the sort.
      */
-    public static int compare_date_descending(Geary.Email aemail, Geary.Email bemail) {
-        return compare_date_ascending(bemail, aemail);
+    public static int compare_sent_date_descending(Geary.Email aemail, Geary.Email bemail) {
+        return compare_sent_date_ascending(bemail, aemail);
+    }
+    
+    /**
+     * CompareFunc to sort { link Email} by { link EmailProperties.date_received} ascending.
+     *
+     * If { link properties} is unavailable on either Email, their identifiers are compared to
+     * stabilize the sort.
+     */
+    public static int compare_recv_date_ascending(Geary.Email aemail, Geary.Email bemail) {
+        if (aemail.properties == null || bemail.properties == null) {
+            GLib.message("Warning: comparing email for received date but email properties not loaded");
+            
+            return compare_id_ascending(aemail, bemail);
+        }
+        
+        int compare = aemail.properties.date_received.compare(bemail.properties.date_received);
+        
+        // stabilize sort with identifiers
+        return (compare != 0) ? compare : compare_id_ascending(aemail, bemail);
+    }
+    
+    /**
+     * CompareFunc to sort { link Email} by { link EmailProperties.date_received} descending.
+     *
+     * If { link properties} is unavailable on either Email, their identifiers are compared to
+     * stabilize the sort.
+     */
+    public static int compare_recv_date_descending(Geary.Email aemail, Geary.Email bemail) {
+        return compare_recv_date_ascending(bemail, aemail);
     }
     
     // only used to stabilize a sort
@@ -394,8 +431,11 @@ public class Geary.Email : BaseObject {
         Geary.EmailProperties? aprop = (Geary.EmailProperties) aemail.properties;
         Geary.EmailProperties? bprop = (Geary.EmailProperties) bemail.properties;
         
-        if (aprop == null || bprop == null)
+        if (aprop == null || bprop == null) {
+            GLib.message("Warning: comparing email by size but email properties not loaded");
+            
             return compare_id_ascending(aemail, bemail);
+        }
         
         int cmp = (int) (aprop.total_bytes - bprop.total_bytes).clamp(-1, 1);
         
@@ -409,26 +449,5 @@ public class Geary.Email : BaseObject {
     public static int compare_size_descending(Geary.Email aemail, Geary.Email bemail) {
         return compare_size_ascending(bemail, aemail);
     }
-    
-    /**
-     * CompareFunc to sort Email by EmailProperties.date_received.  If not available, emails are
-     * compared by EmailIdentifier.
-     */
-    public static int compare_date_received_ascending(Geary.Email aemail, Geary.Email bemail) {
-        if (aemail.properties == null || bemail.properties == null)
-            return compare_id_ascending(aemail, bemail);
-        
-        int cmp = aemail.properties.date_received.compare(bemail.properties.date_received);
-        
-        return (cmp != 0) ? cmp : compare_id_ascending(aemail, bemail);
-    }
-    
-    /**
-     * CompareFunc to sort Email by EmailProperties.date_received.  If not available, emails are
-     * compared by EmailIdentifier.
-     */
-    public static int compare_date_received_descending(Geary.Email aemail, Geary.Email bemail) {
-        return compare_date_received_ascending(bemail, aemail);
-    }
 }
 
diff --git a/src/engine/app/app-conversation.vala b/src/engine/app/app-conversation.vala
index 121a707..92db693 100644
--- a/src/engine/app/app-conversation.vala
+++ b/src/engine/app/app-conversation.vala
@@ -13,8 +13,10 @@ public class Geary.App.Conversation : BaseObject {
      */
     public enum Ordering {
         NONE,
-        DATE_ASCENDING,
-        DATE_DESCENDING,
+        SENT_DATE_ASCENDING,
+        SENT_DATE_DESCENDING,
+        RECV_DATE_ASCENDING,
+        RECV_DATE_DESCENDING
     }
     
     /**
@@ -46,10 +48,14 @@ public class Geary.App.Conversation : BaseObject {
     
     // this isn't ideal but the cost of adding an email to multiple sorted sets once versus
     // the number of times they're accessed makes it worth it
-    private Gee.SortedSet<Email> date_ascending = new Gee.TreeSet<Email>(
-        Geary.Email.compare_date_ascending);
-    private Gee.SortedSet<Email> date_descending = new Gee.TreeSet<Email>(
-        Geary.Email.compare_date_descending);
+    private Gee.SortedSet<Email> sent_date_ascending = new Gee.TreeSet<Email>(
+        Geary.Email.compare_sent_date_ascending);
+    private Gee.SortedSet<Email> sent_date_descending = new Gee.TreeSet<Email>(
+        Geary.Email.compare_sent_date_descending);
+    private Gee.SortedSet<Email> recv_date_ascending = new Gee.TreeSet<Email>(
+        Geary.Email.compare_recv_date_ascending);
+    private Gee.SortedSet<Email> recv_date_descending = new Gee.TreeSet<Email>(
+        Geary.Email.compare_recv_date_descending);
     
     // by storing all paths for each EmailIdentifier, can lookup without blocking
     private Gee.HashMultiMap<Geary.EmailIdentifier, Geary.FolderPath> path_map = new Gee.HashMultiMap<
@@ -120,26 +126,34 @@ public class Geary.App.Conversation : BaseObject {
     }
     
     /**
-     * Returns all the email in the conversation sorted according to the specifier.
+     * Returns all the email in the conversation sorted and filtered according to the specifiers.
      *
      * { link Location.IN_FOLDER} and { link Location.OUT_OF_FOLDER} are the
      * only preferences honored; the others ({ link Location.IN_FOLDER_OUT_OF_FOLDER},
      * { link Location.IN_FOLDER_OUT_OF_FOLDER}, and { link Location.ANYWHERE}
      * are all treated as ANYWHERE.
      */
-    public Gee.List<Geary.Email> get_emails(Ordering ordering, Location location = Location.ANYWHERE) {
-        Gee.List<Geary.Email> list;
+    public Gee.Collection<Geary.Email> get_emails(Ordering ordering, Location location = Location.ANYWHERE) {
+        Gee.Collection<Geary.Email> email;
         switch (ordering) {
-            case Ordering.DATE_ASCENDING:
-                list = Collection.to_array_list<Email>(date_ascending);
+            case Ordering.SENT_DATE_ASCENDING:
+                email = sent_date_ascending;
             break;
             
-            case Ordering.DATE_DESCENDING:
-                list = Collection.to_array_list<Email>(date_descending);
+            case Ordering.SENT_DATE_DESCENDING:
+                email = sent_date_descending;
+            break;
+            
+            case Ordering.RECV_DATE_ASCENDING:
+                email = recv_date_ascending;
+            break;
+            
+            case Ordering.RECV_DATE_DESCENDING:
+                email = recv_date_descending;
             break;
             
             case Ordering.NONE:
-                list = Collection.to_array_list<Email>(emails.values);
+                email = emails.values;
             break;
             
             default:
@@ -148,28 +162,29 @@ public class Geary.App.Conversation : BaseObject {
         
         switch (location) {
             case Location.IN_FOLDER:
-                Collection.remove_if<Email>(list, (email) => {
-                    return !is_in_current_folder(email.id);
-                });
+                email = traverse<Email>(email)
+                    .filter((e) => !is_in_current_folder(e.id))
+                    .to_array_list();
             break;
             
             case Location.OUT_OF_FOLDER:
-                Collection.remove_if<Email>(list, (email) => {
-                    return is_in_current_folder(email.id);
-                });
+                email = traverse<Email>(email)
+                    .filter((e) => is_in_current_folder(e.id))
+                    .to_array_list();
             break;
             
             case Location.IN_FOLDER_OUT_OF_FOLDER:
             case Location.OUT_OF_FOLDER_IN_FOLDER:
             case Location.ANYWHERE:
-                // let the list pass untouched
+                // make a modifiable copy
+                email = traverse<Email>(email).to_array_list();
             break;
             
             default:
                 assert_not_reached();
         }
         
-        return list;
+        return email;
     }
     
     public bool is_in_current_folder(Geary.EmailIdentifier id) {
@@ -214,8 +229,10 @@ public class Geary.App.Conversation : BaseObject {
             return false;
         
         emails.set(email.id, email);
-        date_ascending.add(email);
-        date_descending.add(email);
+        sent_date_ascending.add(email);
+        sent_date_descending.add(email);
+        recv_date_ascending.add(email);
+        recv_date_descending.add(email);
         
         Gee.Set<RFC822.MessageID>? ancestors = email.get_ancestors();
         if (ancestors != null)
@@ -232,8 +249,10 @@ public class Geary.App.Conversation : BaseObject {
     // Returns the removed Message-IDs
     internal Gee.Set<RFC822.MessageID>? remove(Email email) {
         emails.unset(email.id);
-        date_ascending.remove(email);
-        date_descending.remove(email);
+        sent_date_ascending.remove(email);
+        sent_date_descending.remove(email);
+        recv_date_ascending.remove(email);
+        recv_date_descending.remove(email);
         path_map.remove_all(email.id);
         
         Gee.Set<RFC822.MessageID> removed_message_ids = new Gee.HashSet<RFC822.MessageID>();
@@ -276,28 +295,36 @@ public class Geary.App.Conversation : BaseObject {
     
     /**
      * Returns the earliest (first sent) email in the Conversation.
-     *
-     * Note that sorting in { link Conversation} is done by the RFC822 Date: header (i.e.
-     * { link Email.date}) and not the date received (i.e. { link EmailProperties.date_received}).
      */
-    public Geary.Email? get_earliest_email(Location location) {
-        return get_single_email(Ordering.DATE_ASCENDING, location);
+    public Geary.Email? get_earliest_sent_email(Location location) {
+        return get_single_email(Ordering.SENT_DATE_ASCENDING, location);
     }
     
     /**
      * Returns the latest (most recently sent) email in the Conversation.
-     *
-     * Note that sorting in { link Conversation} is done by the RFC822 Date: header (i.e.
-     * { link Email.date}) and not the date received (i.e. { link EmailProperties.date_received}).
      */
-    public Geary.Email? get_latest_email(Location location) {
-        return get_single_email(Ordering.DATE_DESCENDING, location);
+    public Geary.Email? get_latest_sent_email(Location location) {
+        return get_single_email(Ordering.SENT_DATE_DESCENDING, location);
+    }
+    
+    /**
+     * Returns the earliest (first received) email in the Conversation.
+     */
+    public Geary.Email? get_earliest_recv_email(Location location) {
+        return get_single_email(Ordering.RECV_DATE_ASCENDING, location);
+    }
+    
+    /**
+     * Returns the latest (most recently received) email in the Conversation.
+     */
+    public Geary.Email? get_latest_recv_email(Location location) {
+        return get_single_email(Ordering.RECV_DATE_DESCENDING, location);
     }
     
     private Geary.Email? get_single_email(Ordering ordering, Location location) {
         // note that the location-ordering preferences are treated as ANYWHERE by get_emails()
-        Gee.List<Geary.Email> list = get_emails(ordering, location);
-        if (list.size == 0)
+        Gee.Collection<Geary.Email> all = get_emails(ordering, location);
+        if (all.size == 0)
             return null;
         
         // Because IN_FOLDER_OUT_OF_FOLDER and OUT_OF_FOLDER_IN_FOLDER are treated as ANYWHERE,
@@ -306,21 +333,19 @@ public class Geary.App.Conversation : BaseObject {
             case Location.IN_FOLDER:
             case Location.OUT_OF_FOLDER:
             case Location.ANYWHERE:
-                return Collection.get_first<Email>(list);
+                return traverse<Email>(all).first();
             
             case Location.IN_FOLDER_OUT_OF_FOLDER:
-                Geary.Email? found = Collection.find_first<Email>(list, (email) => {
-                    return is_in_current_folder(email.id);
-                });
+                Geary.Email? found = traverse<Email>(all)
+                    .first_matching((email) => is_in_current_folder(email.id));
                 
-                return (found != null) ? found : list.first();
+                return found ?? traverse<Email>(all).first();
             
             case Location.OUT_OF_FOLDER_IN_FOLDER:
-                Geary.Email? found = Collection.find_first<Email>(list, (email) => {
-                    return !is_in_current_folder(email.id);
-                });
+                Geary.Email? found = traverse<Email>(all)
+                    .first_matching((email) => !is_in_current_folder(email.id));
                 
-                return (found != null) ? found : list.first();
+                return found ?? traverse<Email>(all).first();
             
             default:
                 assert_not_reached();
diff --git a/src/engine/imap-engine/imap-engine-email-prefetcher.vala 
b/src/engine/imap-engine/imap-engine-email-prefetcher.vala
index 871963f..ff7dc71 100644
--- a/src/engine/imap-engine/imap-engine-email-prefetcher.vala
+++ b/src/engine/imap-engine/imap-engine-email-prefetcher.vala
@@ -24,7 +24,7 @@ private class Geary.ImapEngine.EmailPrefetcher : Object {
     private int start_delay_sec;
     private Nonblocking.Mutex mutex = new Nonblocking.Mutex();
     private Gee.TreeSet<Geary.Email> prefetch_emails = new Gee.TreeSet<Geary.Email>(
-        Email.compare_date_received_descending);
+        Email.compare_recv_date_descending);
     private uint schedule_id = 0;
     private Cancellable cancellable = new Cancellable();
     
@@ -167,7 +167,7 @@ private class Geary.ImapEngine.EmailPrefetcher : Object {
     private async void do_prefetch_batch_async() throws Error {
         // snarf up all requested Emails for this round
         Gee.TreeSet<Geary.Email> emails = prefetch_emails;
-        prefetch_emails = new Gee.TreeSet<Geary.Email>(Email.compare_date_received_descending);
+        prefetch_emails = new Gee.TreeSet<Geary.Email>(Email.compare_recv_date_descending);
         
         if (emails.size == 0)
             return;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]