]> git.cworth.org Git - sup/blobdiff - lib/sup/modes/contact-list-mode.rb
Merge branch 'preemptive-loading' into next
[sup] / lib / sup / modes / contact-list-mode.rb
index f2f5049a77da93fce6eecf0a2e0ee5c00b9aa893..edbef5e3a27f3f9cba65c8cf1cfaecec05021e3e 100644 (file)
@@ -1,24 +1,47 @@
 module Redwood
 
+module CanAliasContacts
+  def alias_contact p
+    aalias = BufferManager.ask(:alias, "Alias for #{p.longname}: ", ContactManager.alias_for(p))
+    return if aalias.nil?
+    aalias = nil if aalias.empty? # allow empty aliases
+
+    name = BufferManager.ask(:name, "Name for #{p.longname}: ", p.name)
+    return if name.nil? || name.empty? # don't allow empty names
+    p.name = name
+
+    ContactManager.update_alias p, aalias
+    BufferManager.flash "Contact updated!"
+  end
+end
+
 class ContactListMode < LineCursorMode
   LOAD_MORE_CONTACTS_NUM = 10
 
   register_keymap do |k|
     k.add :load_more, "Load #{LOAD_MORE_CONTACTS_NUM} more contacts", 'M'
-    k.add :reload, "Reload contacts", 'R'
-    k.add :alias, "Edit alias for contact", 'a'
+    k.add :reload, "Drop contact list and reload", 'D'
+    k.add :alias, "Edit alias/or name for contact", 'a', 'i'
     k.add :toggle_tagged, "Tag/untag current line", 't'
-    k.add :apply_to_tagged, "Apply next command to all tagged items", ';'
+    k.add :apply_to_tagged, "Apply next command to all tagged items", '+'
     k.add :search, "Search for messages from particular people", 'S'
   end
 
-  def initialize mode = :regular
+  def initialize mode=:regular
     @mode = mode
-    @tags = Tagger.new self
-    reload
+    @tags = Tagger.new self, "contact"
+    @num = nil
+    @text = []
     super()
   end
 
+  include CanAliasContacts
+  def alias
+    p = @contacts[curpos] or return
+    alias_contact p
+    update
+  end
+
   def lines; @text.length; end
   def [] i; @text[i]; end
 
@@ -31,16 +54,16 @@ class ContactListMode < LineCursorMode
 
   def multi_toggle_tagged threads
     @tags.drop_all_tags
-    regen_text
+    update
   end
 
   def apply_to_tagged; @tags.apply_to_tagged; end
 
-  def load; regen_text; end
-  def load_more
-    @num += LOAD_MORE_CONTACTS_NUM
-    regen_text
-    BufferManager.flash "Loaded #{LOAD_MORE_CONTACTS_NUM} more contacts."
+  def load_more num=LOAD_MORE_CONTACTS_NUM
+    @num += num
+    load
+    update
+    BufferManager.flash "Added #{num.pluralize 'contact'}."
   end
 
   def multi_select people
@@ -48,7 +71,7 @@ class ContactListMode < LineCursorMode
     when :regular
       mode = ComposeMode.new :to => people
       BufferManager.spawn "new message", mode
-      mode.edit
+      mode.edit_message
     end
   end
 
@@ -59,8 +82,8 @@ class ContactListMode < LineCursorMode
 
   def multi_search people
     mode = PersonSearchResultsMode.new people
-    BufferManager.spawn "personal search results", mode
-    mode.load_more_threads mode.buffer.content_height
+    BufferManager.spawn "search for #{people.map { |p| p.name }.join(', ')}", mode
+    mode.load_threads :num => mode.buffer.content_height
   end
 
   def search
@@ -70,51 +93,55 @@ class ContactListMode < LineCursorMode
 
   def reload
     @tags.drop_all_tags
-    @num = LOAD_MORE_CONTACTS_NUM
+    @num = nil
     load
   end
 
-  def alias
-    p = @contacts[curpos] or return
-    a = BufferManager.ask(:alias, "alias for #{p.longname}: ", @user_contacts[p]) or return
-    if a.empty?
-      ContactManager.drop_contact p
-    else
-      ContactManager.set_contact p, a
-      @user_contacts[p] = a
-      update_text_for_line curpos
+  def load_in_background
+    Redwood::reporting_thread("contact manager load in bg") do
+      load
+      update
+      BufferManager.draw_screen
     end
   end
 
+  def load
+    @num ||= buffer.content_height
+    @user_contacts = ContactManager.contacts_with_aliases
+    num = [@num - @user_contacts.length, 0].max
+    BufferManager.say("Loading #{num} contacts from index...") do
+      recentc = Index.load_contacts AccountManager.user_emails, :num => num
+      @contacts = (@user_contacts + recentc).sort_by { |p| p.sort_by_me }.uniq
+    end
+  end
+  
 protected
 
+  def update
+    regen_text
+    buffer.mark_dirty if buffer
+  end
+
   def update_text_for_line line
     @text[line] = text_for_contact @contacts[line]
-    buffer.mark_dirty
+    buffer.mark_dirty if buffer
   end
 
   def text_for_contact p
-    aalias = @user_contacts[p] || ""
+    aalias = ContactManager.alias_for(p) || ""
     [[:tagged_color, @tags.tagged?(p) ? ">" : " "],
      [:none, sprintf("%-#{@awidth}s %-#{@nwidth}s %s", aalias, p.name, p.email)]]
   end
 
   def regen_text
-    @user_contacts = ContactManager.contacts.invert
-    recent = Index.load_contacts AccountManager.user_emails,
-                                 :num => @num
-    
-    @contacts = (@user_contacts.keys + recent.select { |p| !@user_contacts[p] }).sort_by { |p| p.sort_by_me + (p.name || "") + p.email }.remove_successive_dupes
-
     @awidth, @nwidth = 0, 0
     @contacts.each do |p|
-      aalias = @user_contacts[p]
+      aalias = ContactManager.alias_for(p)
       @awidth = aalias.length if aalias && aalias.length > @awidth
       @nwidth = p.name.length if p.name && p.name.length > @nwidth
     end
 
     @text = @contacts.map { |p| text_for_contact p }
-    buffer.mark_dirty if buffer
   end
 end