]> git.cworth.org Git - sup/blobdiff - lib/sup/modes/thread-view-mode.rb
'A' archives and kills buffer in thread-view-mode (required significant updatedes...
[sup] / lib / sup / modes / thread-view-mode.rb
index be4079adafb76a0e6086a1e7e01771c5d435b1d1..eeef330b4adb7ebf673f6dff08b54b8828a88ccd 100644 (file)
@@ -26,6 +26,7 @@ class ThreadViewMode < LineCursorMode
     k.add :edit_as_new, "Edit message as new", 'D'
     k.add :save_to_disk, "Save message/attachment to disk", 's'
     k.add :search, "Search for messages from particular people", 'S'
+    k.add :archive_and_kill, "Archive thread and kill buffer", 'A'
   end
 
   ## there are a couple important instance variables we hold to lay
@@ -61,7 +62,7 @@ class ThreadViewMode < LineCursorMode
     @layout[latest].state = :open if @layout[latest].state == :closed
     @layout[earliest].state = :detailed if earliest.has_label?(:unread) || @thread.size == 1
 
-    BufferManager.say("Loading message bodies...") { regen_text }
+    regen_text
   end
 
   def draw_line ln, opts={}
@@ -104,7 +105,7 @@ class ThreadViewMode < LineCursorMode
   def alias
     p = @person_lines[curpos] or return
     alias_contact p
-    regen_text
+    update
   end
 
   def search
@@ -124,13 +125,14 @@ class ThreadViewMode < LineCursorMode
     ## TODO: don't recalculate EVERYTHING just to add a stupid little
     ## star to the display
     update
-    UpdateManager.relay :starred, m
+    UpdateManager.relay self, :starred, m
   end
 
   def toggle_expanded
     chunk = @chunk_lines[curpos] or return
     case chunk
     when Message, Message::Quote, Message::Signature
+      return if chunk.lines.length == 1 unless chunk.is_a? Message # too small to expand/close
       l = @layout[chunk]
       l.state = (l.state != :closed ? :closed : :open)
       cursor_down if l.state == :closed
@@ -235,7 +237,7 @@ class ThreadViewMode < LineCursorMode
 
   def expand_all_quotes
     if(m = @message_lines[curpos])
-      quotes = m.chunks.select { |c| c.is_a?(Message::Quote) || c.is_a?(Message::Signature) }
+      quotes = m.chunks.select { |c| (c.is_a?(Message::Quote) || c.is_a?(Message::Signature)) && c.lines.length > 1 }
       numopen = quotes.inject(0) { |s, c| s + (@layout[c].state == :open ? 1 : 0) }
       newstate = numopen > quotes.length / 2 ? :closed : :open
       quotes.each { |c| @layout[c].state = newstate }
@@ -243,19 +245,18 @@ class ThreadViewMode < LineCursorMode
     end
   end
 
-  ## kinda slow for large threads. TODO: fasterify
   def cleanup
-    BufferManager.say "Marking messages as read..." do
-      @thread.each do |m, d, p|
-        if m && m.has_label?(:unread)
-          m.remove_label :unread 
-          UpdateManager.relay :read, m
-        end
-      end
-    end
+    @thread.remove_label :unread
+    UpdateManager.relay self, :read, @thread
     @layout = @text = nil
   end
 
+  def archive_and_kill
+    @thread.remove_label :inbox
+    UpdateManager.relay self, :archived, @thread
+    BufferManager.kill_buffer_safely buffer
+  end
+
 private 
 
   def initial_state_for m
@@ -286,24 +287,7 @@ private
         @text += chunk_to_lines m, nil, @text.length, depth, parent
         next
       end
-
-      ## we're occasionally called on @threads that have had messages
-      ## added to them since initialization. luckily we regen_text on
-      ## the entire thread every time the user does anything besides
-      ## scrolling (basically), so we can just slap this on here.
-      ##
-      ## to pick nits, the niceness that i do in the constructor with
-      ## 'latest' etc. (for automatically opening just the latest
-      ## message if everything's been read) will not be valid, but
-      ## that's just a nicety and hopefully this won't happen too
-      ## often.
-
-      unless @layout.member? m
-        l = @layout[m] = Layout.new
-        l.state = initial_state_for m
-        l.color = prevm && prevm.color == :message_patina_color ? :alternate_patina_color : :message_patina_color
-      end
-      l = @layout[m]
+      l = @layout[m] or next # TODO: figure out why this is nil sometimes
 
       ## build the patina
       text = chunk_to_lines m, l.state, @text.length, depth, parent, @layout[m].color
@@ -433,22 +417,20 @@ private
       end
       t.map { |line| [[:none, "#{prefix}#{line}"]] }
     when Message::Quote
+      return [[[:quote_color, "#{prefix}#{chunk.lines.first}"]]] if chunk.lines.length == 1
       case state
       when :closed
         [[[:quote_patina_color, "#{prefix}+ (#{chunk.lines.length} quoted lines)"]]]
       when :open
-        t = chunk.lines
-        [[[:quote_patina_color, "#{prefix}- (#{chunk.lines.length} quoted lines)"]]] +
-           t.map { |line| [[:quote_color, "#{prefix}#{line}"]] }
+        [[[:quote_patina_color, "#{prefix}- (#{chunk.lines.length} quoted lines)"]]] + chunk.lines.map { |line| [[:quote_color, "#{prefix}#{line}"]] }
       end
     when Message::Signature
+      return [[[:sig_patina_color, "#{prefix}#{chunk.lines.first}"]]] if chunk.lines.length == 1
       case state
       when :closed
         [[[:sig_patina_color, "#{prefix}+ (#{chunk.lines.length}-line signature)"]]]
       when :open
-        t = chunk.lines
-        [[[:sig_patina_color, "#{prefix}- (#{chunk.lines.length}-line signature)"]]] +
-           t.map { |line| [[:sig_color, "#{prefix}#{line}"]] }
+        [[[:sig_patina_color, "#{prefix}- (#{chunk.lines.length}-line signature)"]]] + chunk.lines.map { |line| [[:sig_color, "#{prefix}#{line}"]] }
       end
     else
       raise "unknown chunk type #{chunk.class.name}"
@@ -457,9 +439,10 @@ private
 
   def view_attachment a
     BufferManager.flash "viewing #{a.content_type} attachment..."
-    a.view!
+    success = a.view!
     BufferManager.erase_flash
     BufferManager.completely_redraw_screen
+    BufferManager.flash "Couldn't execute view command." unless success
   end
 
 end