]> git.cworth.org Git - sup/blob - lib/sup/modes/contact-list-mode.rb
Merge branch 'alignment-tweaks' into next
[sup] / lib / sup / modes / contact-list-mode.rb
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 = 10
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.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     mode.load_threads :num => mode.buffer.content_height
87   end
88
89   def search
90     p = @contacts[curpos] or return
91     multi_search [p]
92   end    
93
94   def reload
95     @tags.drop_all_tags
96     @num = nil
97     load
98   end
99
100   def load_in_background
101     Redwood::reporting_thread("contact manager load in bg") do
102       load
103       update
104       BufferManager.draw_screen
105     end
106   end
107
108   def load
109     @num ||= buffer.content_height
110     @user_contacts = ContactManager.contacts_with_aliases
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      [:none, 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