X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Fsup%2Fmodes%2Fthread-view-mode.rb;h=eeef330b4adb7ebf673f6dff08b54b8828a88ccd;hb=d3093211872207e898cea6f197bd5a29fab3e221;hp=be4079adafb76a0e6086a1e7e01771c5d435b1d1;hpb=8b5803ba5031a000ebd820b675469c74693e5d13;p=sup diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb index be4079a..eeef330 100644 --- a/lib/sup/modes/thread-view-mode.rb +++ b/lib/sup/modes/thread-view-mode.rb @@ -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