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