@state = {}
@hidden_labels = hidden_labels
- earliest = nil
- latest = nil
+ earliest, latest = nil, nil
latest_date = nil
@thread.each do |m, d, p|
next unless m
earliest ||= m
- @state[m] =
- if m.has_label?(:unread) && m == earliest
- :detailed
- elsif m.has_label?(:starred) || m.has_label?(:unread)
- :open
- else
- :closed
- end
+ @state[m] = initial_state_for m
if latest_date.nil? || m.date > latest_date
latest_date = m.date
latest = m
end
end
+
@state[latest] = :open if @state[latest] == :closed
+ @state[earliest] = :detailed if earliest.has_label?(:unread)
BufferManager.say "Loading message bodies..." do
regen_chunks
end
end
- ## not sure if this is really necessary but we might as well...
+ ## kinda slow for large threads. TODO: make faster
def cleanup
- @thread.each do |m, d, p|
- if m && m.has_label?(:unread)
- m.remove_label :unread
- UpdateManager.relay :read, m
+ 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
@messages = @chunks = @text = nil
private
+ def initial_state_for m
+ if m.has_label?(:starred) || m.has_label?(:unread)
+ :open
+ else
+ :closed
+ end
+ end
+
def update
regen_text
buffer.mark_dirty if buffer
prev_m = nil
@thread.each do |m, depth, parent|
+ ## 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' might not be valid, but i don't see that as a huge
+ ## issue.
+ @state[m] ||= initial_state_for m if m
+
text = chunk_to_lines m, @state[m], @text.length, depth, parent
(0 ... text.length).each do |i|
@chunk_lines[@text.length + i] = m
when Message
message_patina_lines(chunk, state, parent, prefix) +
(chunk.is_draft? ? [[[:draft_notification_color, prefix + " >>> This message is a draft. To edit, hit 'e'. <<<"]]] : [])
-
when Message::Attachment
[[[:mime_color, "#{prefix}+ MIME attachment #{chunk.content_type}#{chunk.desc ? ' (' + chunk.desc + ')': ''}"]]]
when Message::Text
attr_reader :containers
def initialize
- raise "wrong thread, buddy!" if block_given?
+ ## ah, the joys of a multithreaded application with a class called
+ ## "Thread". i keep instantiating the wrong one...
+ raise "wrong Thread class, buddy!" if block_given?
@containers = []
end
puts "=== end thread ==="
end
- ## yields each message and some stuff
+ ## yields each message, its depth, and its parent
+ ## note that the message can be a Message object, or :fake_root,
+ ## or nil.
def each fake_root=false
adj = 0
root = @containers.find_all { |c| !Message.subj_is_reply?(c) }.argmin { |c| c.date }
def set_labels l; each { |m, *o| m && m.labels = l }; end
def has_label? t; any? { |m, *o| m && m.has_label?(t) }; end
+ def dirty?; any? { |m, *o| m && m.dirty? }; end
def save index; each { |m, *o| m && m.save(index) }; end
def direct_participants