sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit e8e365f1820a714b3ebb6e08ed0ee3bd3625d2cc
parent b0028987c0b2bd81729d93b2e2a477970f66084a
Author: William Morgan <wmorgan-sup@masanjin.net>
Date:   Tue,  8 Jan 2008 10:04:31 -0800

bugfix: thread correctly in resumed/killed draft messages

the entire thread was being deleted because of UpdateManager changes.
now there are two signals: deleted and single_message_deleted, the first
for thread deletion and the second for draft message removal, and
ThreadIndexMode handles them correctly.

Diffstat:
M lib/sup/draft.rb | 2 +-
M lib/sup/modes/thread-index-mode.rb | 8 ++++++++
M lib/sup/thread.rb | 20 ++++++++++----------
3 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
@@ -36,7 +36,7 @@ class DraftManager
     raise ArgumentError, "not a draft: source id #{entry[:source_id].inspect}, should be #{DraftManager.source_id.inspect} for #{m.id.inspect} / docno #{docid}" unless entry[:source_id].to_i == DraftManager.source_id
     Index.drop_entry docid
     File.delete @source.fn_for_offset(entry[:source_info])
-    UpdateManager.relay self, :deleted, m
+    UpdateManager.relay self, :single_message_deleted, m
   end
 end
 
diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
@@ -156,6 +156,14 @@ EOS
     BufferManager.draw_screen
   end
 
+  def handle_single_message_deleted_update sender, m
+    @ts_mutex.synchronize do
+      return unless @ts.contains? m
+      @ts.remove_id m.id
+    end
+    update
+  end
+
   def handle_deleted_update sender, m
     @ts_mutex.synchronize do
       return unless @ts.contains? m
diff --git a/lib/sup/thread.rb b/lib/sup/thread.rb
@@ -289,7 +289,16 @@ class ThreadSet
     remove_container c
     p.children << c
     c.parent = p
+    update_threading_for c
+  end
+  private :link
+
+  def remove_container c
+    c.parent.children.delete c if c.parent # remove from tree
+  end
+  private :remove_container
 
+  def update_threading_for c
     ## if the child was previously a top-level container, but now is not,
     ## ditch our thread and kill it if necessary
     if c.thread && !c.root?
@@ -298,17 +307,8 @@ class ThreadSet
       c.thread = nil
     end
   end
-  private :link
-
-  def remove_container c
-    c.parent.children.delete c if c.parent # remove from tree
-  end
-  private :remove_container
-
-  def prune_empty_threads; @threads.delete_if { |k, t| t.empty? } end
-  private :prune_empty_threads
+  private :update_threading_for
 
-  ## remove a single message id. not used anywhere, afaik.
   def remove_id mid
     return unless(c = @messages[mid])
     remove_container c