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
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
when :regular
mode = ComposeMode.new :to => people
BufferManager.spawn "new message", mode
- mode.edit
+ mode.edit_message
end
end
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
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