[geary: 7/13] Fixes for conversations that are resurrected



commit 15c5185ddbffd84aca3604e5d1e304607d10f7e7
Author: James Magahern <james magahern com>
Date:   Mon Oct 15 22:40:26 2018 -0700

    Fixes for conversations that are resurrected
    
    1. When conversation is removed via `ConversationSet.remove_conversation`, remove associated email
       ids by finding all ids that map to the conversation being removed, instead of the other way around.
       That way, emails marked as \DELETED will be removed from the conversation set as well.
    2. When a conversation is being evaporated after a flags_changed, use `ConversationMonitor.removed` so
       removed conversations are also removed from the window.
    3. When a conversation is resurrected from a flag change, enqueue an InsertOperation so it actually
       comes back.

 src/engine/app/app-conversation-monitor.vala       | 32 ++++++++++++++--------
 .../conversation-monitor/app-conversation-set.vala | 14 ++++++++--
 2 files changed, 33 insertions(+), 13 deletions(-)
---
diff --git a/src/engine/app/app-conversation-monitor.vala b/src/engine/app/app-conversation-monitor.vala
index 42b65aad..edc0f43e 100644
--- a/src/engine/app/app-conversation-monitor.vala
+++ b/src/engine/app/app-conversation-monitor.vala
@@ -850,11 +850,21 @@ public class Geary.App.ConversationMonitor : BaseObject {
 
     private void on_account_email_flags_changed(Geary.Folder folder,
                                                 Gee.Map<EmailIdentifier,EmailFlags> map) {
+        Gee.HashSet<EmailIdentifier> removed_ids = new Gee.HashSet<EmailIdentifier>();
         Gee.HashSet<Conversation> removed_conversations = new Gee.HashSet<Conversation>();
         foreach (EmailIdentifier id in map.keys) {
             Conversation? conversation = this.conversations.get_by_email_identifier(id);
-            if (conversation == null)
+            if (conversation == null) {
+                if (folder == this.base_folder) {
+                    debug("Unflagging email %s for deletion resurrects conversation", id.to_string());
+
+                    Gee.HashSet<EmailIdentifier> inserted_emails = new Gee.HashSet<EmailIdentifier>();
+                    inserted_emails.add(id);
+                    this.queue.add(new InsertOperation(this, inserted_emails));
+                }
+
                 continue;
+            }
 
             Email? email = conversation.get_email_by_id(id);
             if (email == null)
@@ -866,21 +876,21 @@ public class Geary.App.ConversationMonitor : BaseObject {
             // Remove conversation if get_emails yields an empty collection -- this probably means
             // the conversation was deleted.
             if (conversation.get_emails(Geary.App.Conversation.Ordering.NONE).size == 0) {
-                Logging.debug(Logging.Flag.CONVERSATIONS, 
-                    "Flagging email %s for deletion evaporates conversation %s", 
+                debug("Flagging email %s for deletion evaporates conversation %s", 
                     id.to_string(), conversation.to_string());
                 
-                // Flags may have changed on a conversation that was already removed from this
-                // conversation set.
-                if (this.conversations.read_only_view.contains(conversation)) {
-                    this.conversations.remove_conversation(conversation);
-                }
-                
+                this.conversations.remove_conversation(conversation);
                 removed_conversations.add(conversation);
-            }
+                removed_ids.add(id);
+            } 
         }
 
-        notify_conversations_removed(removed_conversations);
+        // Notify self about removed conversations
+        removed(
+            removed_conversations,
+            new Gee.HashMultiMap<Conversation, Email>(),
+            (folder == this.base_folder) ? removed_ids : null
+        );
     }
 
     private void on_operation_error(ConversationOperation op, Error err) {
diff --git a/src/engine/app/conversation-monitor/app-conversation-set.vala 
b/src/engine/app/conversation-monitor/app-conversation-set.vala
index 91a557a4..451139aa 100644
--- a/src/engine/app/conversation-monitor/app-conversation-set.vala
+++ b/src/engine/app/conversation-monitor/app-conversation-set.vala
@@ -191,8 +191,18 @@ private class Geary.App.ConversationSet : BaseObject {
      * Removes a conversation from the set.
      */
     public void remove_conversation(Conversation conversation) {
-        foreach (Geary.Email conversation_email in conversation.get_emails(Conversation.Ordering.NONE))
-            remove_email_from_conversation(conversation, conversation_email);
+        Gee.HashSet<Geary.EmailIdentifier> ids_to_remove = new Gee.HashSet<Geary.EmailIdentifier>();
+        foreach (Gee.Map.Entry<EmailIdentifier, Conversation> entry in email_id_map.entries) {
+            if (entry.value == conversation) {
+                ids_to_remove.add(entry.key);
+            }
+        }
+
+        foreach (EmailIdentifier id in ids_to_remove) {
+            Geary.Email? email = conversation.get_email_by_id(id);
+            if (email != null)
+                remove_email_from_conversation(conversation, email);
+        }
 
         if (!_conversations.remove(conversation))
             error("Conversation %s already removed from set", conversation.to_string());


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