sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/

lib/sup/modes/contact_list_mode.rb (3693B) - raw

      1 module Redwood
      2 
      3 module CanAliasContacts
      4   def alias_contact p
      5     aalias = BufferManager.ask(:alias, "Alias for #{p.longname}: ", ContactManager.alias_for(p))
      6     return if aalias.nil?
      7     aalias = nil if aalias.empty? # allow empty aliases
      8 
      9     name = BufferManager.ask(:name, "Name for #{p.longname}: ", p.name)
     10     return if name.nil? || name.empty? # don't allow empty names
     11     p.name = name
     12 
     13     ContactManager.update_alias p, aalias
     14     BufferManager.flash "Contact updated!"
     15   end
     16 end
     17 
     18 class ContactListMode < LineCursorMode
     19   LOAD_MORE_CONTACTS_NUM = 100
     20 
     21   register_keymap do |k|
     22     k.add :load_more, "Load #{LOAD_MORE_CONTACTS_NUM} more contacts", 'M'
     23     k.add :reload, "Drop contact list and reload", 'D'
     24     k.add :alias, "Edit alias/or name for contact", 'a', 'i'
     25     k.add :toggle_tagged, "Tag/untag current line", 't'
     26     k.add :apply_to_tagged, "Apply next command to all tagged items", '+'
     27     k.add :search, "Search for messages from particular people", 'S'
     28   end
     29 
     30   def initialize mode=:regular
     31     @mode = mode
     32     @tags = Tagger.new self, "contact"
     33     @num = nil
     34     @text = []
     35     super()
     36   end
     37 
     38   include CanAliasContacts
     39   def alias
     40     p = @contacts[curpos] or return
     41     alias_contact p
     42     update
     43   end
     44 
     45   def lines; @text.length; end
     46   def [] i; @text[i]; end
     47 
     48   def toggle_tagged
     49     p = @contacts[curpos] or return
     50     @tags.toggle_tag_for p
     51     update_text_for_line curpos
     52     cursor_down
     53   end
     54 
     55   def multi_toggle_tagged threads
     56     @tags.drop_all_tags
     57     update
     58   end
     59 
     60   def apply_to_tagged; @tags.apply_to_tagged; end
     61 
     62   def load_more num=LOAD_MORE_CONTACTS_NUM
     63     @num += num
     64     load
     65     update
     66     BufferManager.flash "Added #{num.pluralize 'contact'}."
     67   end
     68 
     69   def multi_select people
     70     case @mode
     71     when :regular
     72       mode = ComposeMode.new :to => people
     73       BufferManager.spawn "new message", mode
     74       mode.default_edit_message
     75     end
     76   end
     77 
     78   def select
     79     p = @contacts[curpos] or return
     80     multi_select [p]
     81   end
     82 
     83   def multi_search people
     84     mode = PersonSearchResultsMode.new people
     85     BufferManager.spawn "search for #{people.map { |p| p.name }.join(', ')}", mode
     86   end
     87 
     88   def search
     89     p = @contacts[curpos] or return
     90     multi_search [p]
     91   end
     92 
     93   def reload
     94     @tags.drop_all_tags
     95     @num = nil
     96     load
     97   end
     98 
     99   def load_in_background
    100     Redwood::reporting_thread("contact manager load in bg") do
    101       load
    102       update
    103       BufferManager.draw_screen
    104     end
    105   end
    106 
    107   def load
    108     @num ||= (buffer.content_height * 2)
    109     @user_contacts = ContactManager.contacts_with_aliases
    110     @user_contacts += (HookManager.run("extra-contact-addresses") || []).map { |addr| Person.from_address addr }
    111     num = [@num - @user_contacts.length, 0].max
    112     BufferManager.say("Loading #{num} contacts from index...") do
    113       recentc = Index.load_contacts AccountManager.user_emails, :num => num
    114       @contacts = (@user_contacts + recentc).sort_by { |p| p.sort_by_me }.uniq
    115     end
    116   end
    117 
    118 protected
    119 
    120   def update
    121     regen_text
    122     buffer.mark_dirty if buffer
    123   end
    124 
    125   def update_text_for_line line
    126     @text[line] = text_for_contact @contacts[line]
    127     buffer.mark_dirty if buffer
    128   end
    129 
    130   def text_for_contact p
    131     aalias = ContactManager.alias_for(p) || ""
    132     [[:tagged_color, @tags.tagged?(p) ? ">" : " "],
    133      [:text_color, sprintf("%-#{@awidth}s %-#{@nwidth}s %s", aalias, p.name, p.email)]]
    134   end
    135 
    136   def regen_text
    137     @awidth, @nwidth = 0, 0
    138     @contacts.each do |p|
    139       aalias = ContactManager.alias_for(p)
    140       @awidth = aalias.length if aalias && aalias.length > @awidth
    141       @nwidth = p.name.length if p.name && p.name.length > @nwidth
    142     end
    143 
    144     @text = @contacts.map { |p| text_for_contact p }
    145   end
    146 end
    147 
    148 end