X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Fsup%2Fmodes%2Flabel-list-mode.rb;h=f65ec2e2080f2f823b1fa102fb77d2cc5f4cbae5;hb=aef0216d7f988ab87a3430c9a65210f0d55dfc64;hp=5c1242fec81bf5436096009333f7597cbe4adffa;hpb=cb521812b954e97b1fe62a113d8447de8fd5417b;p=sup diff --git a/lib/sup/modes/label-list-mode.rb b/lib/sup/modes/label-list-mode.rb index 5c1242f..f65ec2e 100644 --- a/lib/sup/modes/label-list-mode.rb +++ b/lib/sup/modes/label-list-mode.rb @@ -2,79 +2,95 @@ module Redwood class LabelListMode < LineCursorMode register_keymap do |k| - k.add :view_results, "View messages with the selected label", :enter - k.add :reload, "Discard results and reload", 'D' + k.add :select_label, "Search by label", :enter + k.add :reload, "Discard label list and reload", '@' + k.add :jump_to_next_new, "Jump to next new thread", :tab + k.add :toggle_show_unread_only, "Toggle between showing all labels and those with unread mail", 'u' end def initialize @labels = [] @text = [] - super() + @unread_only = false + super + regen_text end - def lines; @text.length; end - def [] i; @text[i]; end + def lines; @text.length end + def [] i; @text[i] end - def load_in_background - Redwood::reporting_thread do - BufferManager.say("Counting labels...") { regen_text } - BufferManager.draw_screen + def jump_to_next_new + n = ((curpos + 1) ... lines).find { |i| @labels[i][1] > 0 } || (0 ... curpos).find { |i| @labels[i][1] > 0 } + if n + ## jump there if necessary + jump_to_line n unless n >= topline && n < botline + set_cursor_pos n + else + BufferManager.flash "No labels messages with unread messages." end end + def focus + reload # make sure unread message counts are up-to-date + end + protected + def toggle_show_unread_only + @unread_only = !@unread_only + reload + end + def reload - buffer.mark_dirty - BufferManager.draw_screen - load_in_background + regen_text + buffer.mark_dirty if buffer end - + def regen_text @text = [] - @labels = (LabelManager::LISTABLE_LABELS + LabelManager.user_labels).sort_by { |t| t.to_s } + labels = LabelManager.all_labels - counts = @labels.map do |t| - total = Index.num_results_for :label => t - unread = Index.num_results_for :labels => [t, :unread] - [t, total, unread] - end + counts = labels.map do |label| + string = LabelManager.string_for label + total = Index.num_results_for :label => label + unread = (label == :unread)? total : Index.num_results_for(:labels => [label, :unread]) + [label, string, total, unread] + end.sort_by { |l, s, t, u| s.downcase } - width = @labels.map { |t| t.to_s.length }.max + width = counts.max_of { |l, s, t, u| s.length } - counts.map_with_index do |(t, total, unread), i| - if total == 0 && !LabelManager::LISTABLE_LABELS.include?(t) - Redwood::log "no hits for label #{t}, deleting" - LabelManager.delete t - @labels.delete t + if @unread_only + counts.delete_if { | l, s, t, u | u == 0 } + end + + @labels = [] + counts.map do |label, string, total, unread| + ## if we've done a search and there are no messages for this label, we can delete it from the + ## list. BUT if it's a brand-new label, the user may not have sync'ed it to the index yet, so + ## don't delete it in this case. + ## + ## this is all a hack. what should happen is: + ## TODO make the labelmanager responsible for label counts + ## and then it can listen to labeled and unlabeled events, etc. + if total == 0 && !LabelManager::RESERVED_LABELS.include?(label) && !LabelManager.new_label?(label) + debug "no hits for label #{label}, deleting" + LabelManager.delete label next end - label = - case t - when *LabelManager::LISTABLE_LABELS - t.to_s.ucfirst - else - t.to_s - end @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color), - sprintf("%#{width + 1}s %5d %s, %5d unread", label, total, total == 1 ? " message" : "messages", unread)]] + sprintf("%#{width + 1}s %5d %s, %5d unread", string, total, total == 1 ? " message" : "messages", unread)]] + @labels << [label, unread] yield i if block_given? end.compact - buffer.mark_dirty + BufferManager.flash "No labels with unread messages!" if counts.empty? && @unread_only end - def view_results - label = @labels[curpos] - if label == :inbox - BufferManager.raise_to_front BufferManager["inbox"] - else - b = BufferManager.spawn_unless_exists(label) do - mode = LabelSearchResultsMode.new [label] - end - b.mode.load_threads :num => b.content_height - end + def select_label + label, num_unread = @labels[curpos] + return unless label + LabelSearchResultsMode.spawn_nicely label end end