lib/sup/modes/thread-index-mode.rb in sup-0.1 vs lib/sup/modes/thread-index-mode.rb in sup-0.2

- old
+ new

@@ -8,23 +8,23 @@ FROM_WIDTH = 15 LOAD_MORE_THREAD_NUM = 20 register_keymap do |k| k.add :load_threads, "Load #{LOAD_MORE_THREAD_NUM} more threads", 'M' - k.add :reload, "Discard threads and reload", 'D' + 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' k.add :edit_message, "Edit message (drafts only)", 'e' - k.add :mark_as_spam, "Mark thread as spam", 'S' - k.add :delete, "Mark thread for deletion", 'd' + k.add :toggle_spam, "Mark/unmark thread as spam", 'S' + k.add :toggle_deleted, "Delete/undelete thread", 'd' k.add :kill, "Kill thread (never to be seen in inbox again)", '&' k.add :save, "Save changes now", '$' k.add :jump_to_next_new, "Jump to next new thread", :tab - k.add :reply, "Reply to a thread", 'r' - k.add :forward, "Forward a thread", 'f' + k.add :reply, "Reply to latest message in a thread", 'r' + k.add :forward, "Forward latest message in a thread", 'f' k.add :toggle_tagged, "Tag/untag current line", 't' k.add :apply_to_tagged, "Apply next command to all tagged threads", ';' end def initialize hidden_labels=[], load_thread_opts={} @@ -78,21 +78,20 @@ mode.jump_to_first_open BufferManager.draw_screen # lame TODO: make this unnecessary ## the first draw_screen is needed before topline and botline ## are set, and the second to show the cursor having moved - t.remove_label :unread update_text_for_line curpos UpdateManager.relay self, :read, t end end def multi_select threads threads.each { |t| select t } end - def handle_starred_update sender, m + def handle_label_update sender, m t = @ts.thread_for(m) or return l = @lines[t] or return update_text_for_line l BufferManager.draw_screen end @@ -103,10 +102,16 @@ 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 + hide_thread t + regen_text + end + ## overwrite me! def is_relevant? m; false; end def handle_add_update sender, m if is_relevant?(m) || @ts.is_relevant?(m) @@ -143,12 +148,14 @@ end 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 else t.first.add_label :starred # add only to first + UpdateManager.relay self, :starred, t end end def toggle_starred t = @threads[curpos] or return @@ -170,10 +177,30 @@ t.apply_label :inbox UpdateManager.relay self, :unarchived, t end end + def actually_toggle_spammed t + if t.has_label? :spam + t.remove_label :spam + UpdateManager.relay self, :unspammed, t + else + t.apply_label :spam + UpdateManager.relay self, :spammed, t + end + end + + def actually_toggle_deleted t + if t.has_label? :deleted + t.remove_label :deleted + UpdateManager.relay self, :undeleted, t + else + t.apply_label :deleted + UpdateManager.relay self, :deleted, t + end + end + def toggle_archived t = @threads[curpos] or return actually_toggle_archived t update_text_for_line curpos end @@ -209,32 +236,40 @@ else BufferManager.flash "No new messages" end end - def mark_as_spam + def toggle_spam t = @threads[curpos] or return - multi_mark_as_spam [t] + multi_toggle_spam [t] end - def multi_mark_as_spam threads + ## both spam and deleted have the curious characteristic that you + ## always want to hide the thread after either applying or removing + ## that label. in all thread-index-views except for + ## label-search-results-mode, when you mark a message as spam or + ## deleted, you want it to disappear immediately; in LSRM, you only + ## see deleted or spam emails, and when you undelete or unspam them + ## you also want them to disappear immediately. + def multi_toggle_spam threads threads.each do |t| - t.toggle_label :spam - hide_thread t + actually_toggle_spammed t + hide_thread t end regen_text end - def delete + def toggle_deleted t = @threads[curpos] or return - multi_delete [t] + multi_toggle_deleted [t] end - def multi_delete threads + ## see comment for multi_toggle_spam + def multi_toggle_deleted threads threads.each do |t| - t.toggle_label :deleted - hide_thread t + actually_toggle_deleted t + hide_thread t end regen_text end def kill @@ -246,10 +281,11 @@ threads.each do |t| t.apply_label :killed hide_thread t end regen_text + BufferManager.flash "Thread#{threads.size == 1 ? '' : 's'} killed." end def save dirty_threads = (@threads + @hidden_threads.keys).select { |t| t.dirty? } return if dirty_threads.empty? @@ -286,24 +322,16 @@ def edit_labels thread = @threads[curpos] or return speciall = (@hidden_labels + LabelManager::RESERVED_LABELS).uniq keepl, modifyl = thread.labels.partition { |t| speciall.member? t } - label_string = modifyl.join(" ") - label_string += " " unless label_string.empty? - answer = BufferManager.ask :edit_labels, "edit labels: ", label_string - return unless answer - user_labels = answer.split(/\s+/).map { |l| l.intern } - - hl = user_labels.select { |l| speciall.member? l } - if hl.empty? - thread.labels = keepl + user_labels - user_labels.each { |l| LabelManager << l } - else - BufferManager.flash "'#{hl}' is a reserved label!" - end + 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 end def multi_edit_labels threads answer = BufferManager.ask :add_labels, "add labels: " @@ -334,11 +362,11 @@ m = t.latest_message return if m.nil? # probably won't happen m.load_from_source! mode = ForwardMode.new m BufferManager.spawn "Forward of #{m.subj}", mode - mode.edit + mode.edit_message end def load_n_threads_background n=LOAD_MORE_THREAD_NUM, opts={} return if @load_thread # todo: wrap in mutex @load_thread = Redwood::reporting_thread do @@ -382,12 +410,12 @@ n = opts[:num] || ThreadIndexMode::LOAD_MORE_THREAD_NUM 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} threads" + BufferManager.flash "Found #{num} threads." else - BufferManager.flash "No matches" + BufferManager.flash "No matches." end end)}) if opts[:background] || opts[:background].nil? load_n_threads_background n, myopts