]> git.cworth.org Git - sup/commitdiff
fix (mostly!) the updates system
authorwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Mon, 10 Dec 2007 02:50:49 +0000 (02:50 +0000)
committerwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Mon, 10 Dec 2007 02:50:49 +0000 (02:50 +0000)
git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@756 5c8cc53c-5e98-4d25-b20a-d8db53a31250

lib/sup/draft.rb
lib/sup/modes/inbox-mode.rb
lib/sup/modes/label-search-results-mode.rb
lib/sup/modes/resume-mode.rb
lib/sup/modes/thread-index-mode.rb
lib/sup/modes/thread-view-mode.rb
lib/sup/poll.rb
lib/sup/sent.rb
lib/sup/thread.rb
lib/sup/update.rb

index 5db89fdcf55fea240f57b09eb4969f71e8771dbb..eb2b4e1b56fbcac8e8854f4ca995af921e686649 100644 (file)
@@ -23,20 +23,20 @@ class DraftManager
     @source.each do |thisoffset, theselabels|
       m = Message.new :source => @source, :source_info => thisoffset, :labels => theselabels
       Index.sync_message m
-      UpdateManager.relay self, :add, m
+      UpdateManager.relay self, :added, m
       my_message = m if thisoffset == offset
     end
 
     my_message
   end
 
-  def discard mid
-    docid, entry = Index.load_entry_for_id mid
-    raise ArgumentError, "can't find entry for draft: #{mid.inspect}" unless entry
-    raise ArgumentError, "not a draft: source id #{entry[:source_id].inspect}, should be #{DraftManager.source_id.inspect} for #{mid.inspect} / docno #{docid}" unless entry[:source_id].to_i == DraftManager.source_id
+  def discard m
+    docid, entry = Index.load_entry_for_id m.id
+    raise ArgumentError, "can't find entry for draft: #{m.id.inspect}" unless entry
+    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, :delete, mid
+    UpdateManager.relay self, :deleted, m
   end
 end
 
index 10e8ba6bb12dc65dc6660533eecd979e4250096d..a2de13fc5b6717d36052741bba7341d7d8153525 100644 (file)
@@ -38,11 +38,14 @@ class InboxMode < ThreadIndexMode
     regen_text
   end
 
-  def handle_archived_update sender, t
-    if contains_thread? t
-      hide_thread t
-      regen_text
-    end
+  def handle_unarchived_update sender, m
+    add_or_unhide m
+  end
+
+  def handle_archived_update sender, m
+    t = thread_containing(m) or return
+    hide_thread t
+    regen_text
   end
 
   def status
index 3f4df9db35e587182aba3bce11eef0fe8407e761..88e359548b0bd15698a86a7f8ae35fb3c2a12a15 100644 (file)
@@ -9,7 +9,7 @@ class LabelSearchResultsMode < ThreadIndexMode
     super [], opts
   end
 
-  def is_relevant? m; @labels.all? { |l| m.has_label? l }; end
+  def is_relevant? m; @labels.all? { |l| m.has_label? l } end
 
   def self.spawn_nicely label
     label = LabelManager.label_for(label) unless label.is_a?(Symbol)
index 3cc9992d78356e7b02b2149cae3c3e4689cb3507..34709757e049260c0044ad0bac49b6ffc6d86b03 100644 (file)
@@ -2,7 +2,7 @@ module Redwood
 
 class ResumeMode < EditMessageMode
   def initialize m
-    @id = m.id
+    @m = m
     @safe = false
 
     header, body = parse_file m.draft_filename
@@ -16,13 +16,13 @@ class ResumeMode < EditMessageMode
 
     case BufferManager.ask_yes_or_no "Discard draft?"
     when true
-      DraftManager.discard @id
+      DraftManager.discard @m
       BufferManager.flash "Draft discarded."
       true
     when false
       if edited?
         DraftManager.write_draft { |f| write_message f, false }
-        DraftManager.discard @id
+        DraftManager.discard @m
         BufferManager.flash "Draft saved."
       end
       true
@@ -33,14 +33,14 @@ class ResumeMode < EditMessageMode
 
   def send_message
     if super
-      DraftManager.discard @id 
+      DraftManager.discard @m 
       @safe = true
     end
   end
 
   def save_as_draft
     @safe = true
-    DraftManager.discard @id if super
+    DraftManager.discard @m if super
   end
 end
 
index 8727e2428f0fd0e99f2fd9aa8ddf3412e8527a89..be5fc8e7f1a960592fb92deac611d81299f7e1f0 100644 (file)
@@ -97,7 +97,7 @@ EOS
       ## are set, and the second to show the cursor having moved
 
       update_text_for_line curpos
-      UpdateManager.relay self, :read, t
+      UpdateManager.relay self, :read, t.first
     end
   end
 
@@ -105,27 +105,31 @@ EOS
     threads.each { |t| select t }
   end
   
-  def handle_label_update sender, m
-    t = @ts_mutex.synchronize { @ts.thread_for(m) } or return
-    handle_label_thread_update sender, t
+  def handle_single_message_labeled_update sender, m
+    ## no need to do anything different here; we don't differentiate 
+    ## messages from their containing threads
+    handle_labeled_update sender, m
+  end
+
+  def handle_labeled_update sender, m
+    if(t = thread_containing(m)) 
+      l = @lines[t] or return
+      update_text_for_line l
+    elsif is_relevant?(m)
+      add_or_unhide m
+    end
   end
 
-  def handle_label_thread_update sender, t
+  def handle_read_update sender, m
+    t = thread_containing(m) or return
     l = @lines[t] or return
     update_text_for_line l
-    BufferManager.draw_screen
-  end
-
-  def handle_read_update sender, t
-    l = @lines[t] or return
-    update_text_for_line l
-    BufferManager.draw_screen
   end
 
   def handle_archived_update *a; handle_read_update(*a); end
 
-  def handle_deleted_update sender, t
-    handle_read_update sender, t
+  def handle_deleted_update sender, m
+    t = thread_containing(m) or return
     hide_thread t
     regen_text
   end
@@ -133,22 +137,21 @@ EOS
   ## overwrite me!
   def is_relevant? m; false; end
 
-  def handle_add_update sender, m
-    @ts_mutex.synchronize do
-      return unless is_relevant?(m) || @ts.is_relevant?(m)
-      @ts.load_thread_for_message m
-    end
-    update
+  def handle_added_update sender, m
+    add_or_unhide m
     BufferManager.draw_screen
   end
 
-  def handle_delete_update sender, mid
+  def handle_deleted_update sender, m
     @ts_mutex.synchronize do
-      return unless @ts.contains_id? mid
-      @ts.remove mid
+      return unless @ts.contains? m
+      @ts.remove_id m.id
     end
     update
-    BufferManager.draw_screen
+  end
+
+  def handle_undeleted_update sender, m
+    add_or_unhide m
   end
 
   def update
@@ -176,10 +179,10 @@ EOS
   def actually_toggle_starred t
     if t.has_label? :starred # if ANY message has a star
       t.remove_label :starred # remove from all
-      UpdateManager.relay self, :unstarred, t
+      UpdateManager.relay self, :unstarred, t.first
     else
       t.first.add_label :starred # add only to first
-      UpdateManager.relay self, :starred, t
+      UpdateManager.relay self, :starred, t.first
     end
   end  
 
@@ -198,30 +201,30 @@ EOS
   def actually_toggle_archived t
     if t.has_label? :inbox
       t.remove_label :inbox
-      UpdateManager.relay self, :archived, t
+      UpdateManager.relay self, :archived, t.first
     else
       t.apply_label :inbox
-      UpdateManager.relay self, :unarchived, t
+      UpdateManager.relay self, :unarchived, t.first
     end
   end
 
   def actually_toggle_spammed t
     if t.has_label? :spam
       t.remove_label :spam
-      UpdateManager.relay self, :unspammed, t
+      UpdateManager.relay self, :unspammed, t.first
     else
       t.apply_label :spam
-      UpdateManager.relay self, :spammed, t
+      UpdateManager.relay self, :spammed, t.first
     end
   end
 
   def actually_toggle_deleted t
     if t.has_label? :deleted
       t.remove_label :deleted
-      UpdateManager.relay self, :undeleted, t
+      UpdateManager.relay self, :undeleted, t.first
     else
       t.apply_label :deleted
-      UpdateManager.relay self, :deleted, t
+      UpdateManager.relay self, :deleted, t.first
     end
   end
 
@@ -372,7 +375,7 @@ EOS
     return unless user_labels
     thread.labels = keepl + user_labels
     user_labels.each { |l| LabelManager << l }
-    update_text_for_line curpos
+    UpdateManager.relay self, :labeled, thread.first
   end
 
   def multi_edit_labels threads
@@ -474,6 +477,23 @@ EOS
 
 protected
 
+  def add_or_unhide m
+    if @hidden_threads[m]
+      @hidden_threads.delete m
+      ## now it will re-appear when #update is called
+    else
+      Redwood::log "#{self}: adding: #{m}"
+      @ts_mutex.synchronize do
+        return unless is_relevant?(m) || @ts.is_relevant?(m)
+        @ts.load_thread_for_message m
+      end
+    end
+
+    update
+  end
+
+  def thread_containing m; @ts_mutex.synchronize { @ts.thread_for m } end
+
   ## used to tag threads by query. this can be made a lot more sophisticated,
   ## but for right now we'll do the obvious this.
   def thread_match? t, query
index fbe6351c3997c27509edf1d901d35fe7dcdb9635..1f0078365e5ffba122bd4c499aa93238b15a4612 100644 (file)
@@ -171,7 +171,7 @@ EOS
     @thread.labels = (reserved_labels + new_labels).uniq
     new_labels.each { |l| LabelManager << l }
     update
-    UpdateManager.relay self, :label_thread, @thread
+    UpdateManager.relay self, :labeled, @thread.first
   end
 
   def toggle_starred
@@ -193,7 +193,7 @@ EOS
     ## TODO: don't recalculate EVERYTHING just to add a stupid little
     ## star to the display
     update
-    UpdateManager.relay self, :label, m
+    UpdateManager.relay self, :single_message_labeled, m
   end
 
   ## called when someone presses enter when the cursor is highlighting
@@ -331,13 +331,13 @@ EOS
 
   def archive_and_kill
     @thread.remove_label :inbox
-    UpdateManager.relay self, :archived, @thread
+    UpdateManager.relay self, :archived, @thread.first
     BufferManager.kill_buffer_safely buffer
   end
 
   def delete_and_kill
     @thread.apply_label :deleted
-    UpdateManager.relay self, :deleted, @thread
+    UpdateManager.relay self, :deleted, @thread.first
     BufferManager.kill_buffer_safely buffer
   end
 
index 387f06e34af5ef7665c2cf3f749ab8c8770b504e..2b9a9c5c310d71037527ba8d9461d57992f9cd5b 100644 (file)
@@ -157,7 +157,7 @@ EOS
           HookManager.run "before-add-message", :message => m
           m = yield(m, offset, entry) or next
           Index.sync_message m, docid, entry
-          UpdateManager.relay self, :add, m unless entry
+          UpdateManager.relay self, :added, m unless entry
         rescue MessageFormatError => e
           Redwood::log "ignoring erroneous message at #{source}##{offset}: #{e.message}"
         end
index 05a88b9239c1f36d8bdf83911979445dc72114d4..9c802d9673a4247cff3f0a999b262cfc8edc495e 100644 (file)
@@ -25,7 +25,7 @@ class SentManager
     @source.each do |offset, labels|
       m = Message.new :source => @source, :source_info => offset, :labels => @source.labels
       Index.sync_message m
-      UpdateManager.relay self, :add, m
+      UpdateManager.relay self, :added, m
     end
   end
 end
index d4593035336134736a63f11322cd81948ee9dc10..880feb6c7c8e1a8626b2c648dede14dbc455f39d 100644 (file)
@@ -11,7 +11,7 @@
 ## zero or more Threads. A Thread represents all the message related
 ## to a particular subject. Each Thread has one or more Containers.  A
 ## Container is a recursive structure that holds the message tree as
-## determined by the references: and in-reply-to: headers. EAch
+## determined by the references: and in-reply-to: headers. Each
 ## Container holds zero or one messages. In the case of zero messages,
 ## it means we've seen a reference to the message but haven't (yet)
 ## seen the message itself.
@@ -252,10 +252,10 @@ class ThreadSet
     @thread_by_subj = thread_by_subj
   end
 
-  def contains_id? id; @messages.member?(id) && !@messages[id].empty?; end
-  def thread_for m
-    (c = @messages[m.id]) && c.root.thread
-  end
+  def thread_for_id mid; (c = @messages[mid]) && c.root.thread end
+  def contains_id? id; @messages.member?(id) && !@messages[id].empty? end
+  def thread_for m; thread_for_id m.id end
+  def contains? m; contains_id? m.id end
 
   def delete_cruft
     @threads.each { |k, v| @threads.delete(k) if v.empty? }
@@ -293,7 +293,7 @@ class ThreadSet
   end
   private :link
 
-  def remove mid
+  def remove_id mid
     return unless(c = @messages[mid])
 
     c.parent.children.delete c if c.parent
index 9c28fdb0e948a5cd0bb398c290b733e641849e43..655573ea95f69c39fafc3b733628faf42f695378 100644 (file)
@@ -1,5 +1,18 @@
 module Redwood
 
+## Classic listener/sender paradigm. Handles communication between various
+## parts of Sup.
+##
+## Usage note: don't pass threads around. Neither thread nor message equality
+## is defined beyond standard object equality. For Thread equality, this is
+## because of computational cost. But message equality is trivial by comparing
+## message ids, so to communicate something about a particular thread, just
+## pass a representative message from it instead.
+##
+## This assumes that no message will be a part of more than one thread within
+## a single "view" (otherwise a message from a thread wouldn't uniquely
+## identify it). But that's true.
+
 class UpdateManager
   include Singleton