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