lib/sup/modes/thread-index-mode.rb in sup-0.4 vs lib/sup/modes/thread-index-mode.rb in sup-0.5
- old
+ new
@@ -14,10 +14,14 @@
thread: The message thread to be formatted.
EOS
register_keymap do |k|
k.add :load_threads, "Load #{LOAD_MORE_THREAD_NUM} more threads", 'M'
+ k.add_multi "Load all threads (! to confirm) :", '!' do |kk|
+ kk.add :load_all_threads, "Load all threads (may list a _lot_ of threads)", '!'
+ end
+ k.add :cancel_search, "Cancel current search", :ctrl_g
k.add :reload, "Refresh view", '@'
k.add :toggle_archived, "Toggle archived status", 'a'
k.add :toggle_starred, "Star or unstar all messages in thread", '*'
k.add :toggle_new, "Toggle new/read status of all messages in thread", 'N'
k.add :edit_labels, "Edit or add labels for a thread", 'l'
@@ -48,10 +52,12 @@
## these guys, and @text and @lines, are not covered
@load_thread = nil
@load_thread_opts = load_thread_opts
@hidden_labels = hidden_labels + LabelManager::HIDDEN_RESERVED_LABELS
@date_width = DATE_WIDTH
+
+ @interrupt_search = false
initialize_threads # defines @ts and @ts_mutex
update # defines @text and @lines
UpdateManager.register self
@@ -105,23 +111,36 @@
def multi_select threads
threads.each { |t| select t }
end
- ## this is called by thread-view-modes when the user wants to view
- ## the next thread without going to index-mode. we update the cursor
- ## as a convenience.
+ ## these two methods are called by thread-view-modes when the user
+ ## wants to view the previous/next thread without going back to
+ ## index-mode. we update the cursor as a convenience.
def launch_next_thread_after thread, &b
+ launch_another_thread thread, 1, &b
+ end
+
+ def launch_prev_thread_before thread, &b
+ launch_another_thread thread, -1, &b
+ end
+
+ def launch_another_thread thread, direction, &b
l = @lines[thread] or return
+ target_l = l + direction
t = @mutex.synchronize do
- if l < @threads.length - 1
- set_cursor_pos l + 1 # move out of mutex?
- @threads[l + 1]
+ if target_l >= 0 && target_l < @threads.length
+ @threads[target_l]
end
- end or return
+ end
- select t, b
+ if t # there's a next thread
+ set_cursor_pos target_l # move out of mutex?
+ select t, b
+ elsif b # no next thread. call the block anyways
+ b.call
+ end
end
def handle_single_message_labeled_update sender, m
## no need to do anything different here; we don't differentiate
## messages from their containing threads
@@ -164,17 +183,23 @@
end
update
end
def handle_deleted_update sender, m
- @ts_mutex.synchronize do
- return unless @ts.contains? m
- @ts.remove_thread_containing_id m.id
- end
+ t = @ts_mutex.synchronize { @ts.thread_for m }
+ return unless t
+ hide_thread t
update
end
+ def handle_spammed_update sender, m
+ t = @ts_mutex.synchronize { @ts.thread_for m }
+ return unless t
+ hide_thread t
+ update
+ end
+
def handle_undeleted_update sender, m
add_or_unhide m
end
def update
@@ -408,10 +433,11 @@
user_labels = BufferManager.ask_for_labels :label, "Labels for thread: ", modifyl, @hidden_labels
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
answer = BufferManager.ask :add_labels, "add labels: "
@@ -454,20 +480,26 @@
end
end
## TODO: figure out @ts_mutex in this method
def load_n_threads n=LOAD_MORE_THREAD_NUM, opts={}
+ @interrupt_search = false
@mbid = BufferManager.say "Searching for threads..."
+
+ ts_to_load = n
+ ts_to_load = ts_to_load + @ts.size unless n == -1 # -1 means all threads
+
orig_size = @ts.size
last_update = Time.now
- @ts.load_n_threads(@ts.size + n, opts) do |i|
+ @ts.load_n_threads(ts_to_load, opts) do |i|
if (Time.now - last_update) >= 0.25
BufferManager.say "Loaded #{i.pluralize 'thread'}...", @mbid
update
BufferManager.draw_screen
last_update = Time.now
end
+ break if @interrupt_search
end
@ts.threads.each { |th| th.labels.each { |l| LabelManager << l } }
update
BufferManager.clear @mbid
@@ -483,15 +515,28 @@
else
"line #{curpos + 1} of #{l} #{dirty? ? '*modified*' : ''}"
end
end
+ def cancel_search
+ @interrupt_search = true
+ end
+
+ def load_all_threads
+ load_threads :num => -1
+ end
+
def load_threads opts={}
- n = opts[:num] || ThreadIndexMode::LOAD_MORE_THREAD_NUM
+ if opts[:num].nil?
+ n = ThreadIndexMode::LOAD_MORE_THREAD_NUM
+ else
+ n = opts[:num]
+ end
myopts = @load_thread_opts.merge({ :when_done => (lambda do |num|
opts[:when_done].call(num) if opts[:when_done]
+
if num > 0
BufferManager.flash "Found #{num.pluralize 'thread'}."
else
BufferManager.flash "No matches."
end
@@ -511,18 +556,16 @@
end
protected
def add_or_unhide m
- if @hidden_threads[m]
- @hidden_threads.delete m
- ## now it will re-appear when #update is called
- else
- @ts_mutex.synchronize do
- return unless is_relevant?(m) || @ts.is_relevant?(m)
+ @ts_mutex.synchronize do
+ if (is_relevant?(m) || @ts.is_relevant?(m)) && !@ts.contains?(m)
@ts.load_thread_for_message m
end
+
+ @hidden_threads.delete @ts.thread_for(m)
end
update
end
@@ -610,11 +653,10 @@
def text_for_thread_at line
t, size_widget = @mutex.synchronize { [@threads[line], @size_widgets[line]] }
date = t.date.to_nice_s
- new = t.has_label?(:unread)
starred = t.has_label?(:starred)
## format the from column
cur_width = 0
ann = author_names_and_newness_for_thread t
@@ -647,10 +689,12 @@
dp = t.direct_participants.any? { |p| AccountManager.is_account? p }
p = dp || t.participants.any? { |p| AccountManager.is_account? p }
subj_color =
- if new
+ if t.has_label?(:draft)
+ :index_draft_color
+ elsif t.has_label?(:unread)
:index_new_color
elsif starred
:index_starred_color
else
:index_old_color