Mercurial > libervia-web
comparison src/browser/sat_browser/contact_list.py @ 647:e0021d571eef frontends_multi_profiles
browser side: moved ContactBox, ContactsPanel, ContactLabeland ContactMenuBar to base_widget/base_panels so they can be reused outside of contact_list module
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 26 Feb 2015 13:10:46 +0100 |
parents | f5145881723a |
children | 6d3142b782c3 |
comparison
equal
deleted
inserted
replaced
646:9972a24592b0 | 647:e0021d571eef |
---|---|
24 from pyjamas.ui.SimplePanel import SimplePanel | 24 from pyjamas.ui.SimplePanel import SimplePanel |
25 from pyjamas.ui.ScrollPanel import ScrollPanel | 25 from pyjamas.ui.ScrollPanel import ScrollPanel |
26 from pyjamas.ui.VerticalPanel import VerticalPanel | 26 from pyjamas.ui.VerticalPanel import VerticalPanel |
27 from pyjamas.ui.ClickListener import ClickHandler | 27 from pyjamas.ui.ClickListener import ClickHandler |
28 from pyjamas.ui.Label import Label | 28 from pyjamas.ui.Label import Label |
29 from pyjamas.ui.HTML import HTML | |
30 from pyjamas.ui.Image import Image | |
31 from pyjamas import Window | 29 from pyjamas import Window |
32 from pyjamas import DOM | 30 from pyjamas import DOM |
33 from __pyjamas__ import doc | 31 from __pyjamas__ import doc |
34 | 32 |
35 from sat_frontends.tools import jid | |
36 from constants import Const as C | 33 from constants import Const as C |
37 import base_widget | 34 import base_widget |
38 import html_tools | 35 import base_panels |
36 import blog | |
39 import chat | 37 import chat |
40 import blog | |
41 | |
42 | 38 |
43 unicode = str # XXX: pyjama doesn't manage unicode | 39 unicode = str # XXX: pyjama doesn't manage unicode |
44 | 40 |
45 | 41 |
46 def buildPresenceStyle(presence, base_style=None): | 42 def buildPresenceStyle(presence, base_style=None): |
88 ClickHandler.__init__(self) | 84 ClickHandler.__init__(self) |
89 self.addClickListener(self) | 85 self.addClickListener(self) |
90 | 86 |
91 def onClick(self, sender): | 87 def onClick(self, sender): |
92 self.host.displayWidget(blog.MicroblogPanel, self.group) | 88 self.host.displayWidget(blog.MicroblogPanel, self.group) |
93 | |
94 | |
95 class ContactLabel(HTML): | |
96 """Display a contact in HTML, selecting best display (jid/nick/etc)""" | |
97 | |
98 def __init__(self, host, jid_): | |
99 # TODO: add a listener for nick changes | |
100 HTML.__init__(self) | |
101 self.host = host | |
102 self.jid = jid_.bare | |
103 self.nick = self.host.contact_lists[C.PROF_KEY_NONE].getCache(self.jid, "nick") | |
104 self.alert = False | |
105 self.refresh() | |
106 self.setStyleName('contactLabel') | |
107 | |
108 def refresh(self): | |
109 alert_html = "<strong>(*)</strong> " if self.alert else "" | |
110 contact_html = html_tools.html_sanitize(self.nick or unicode(self.jid)) | |
111 html = "%(alert)s%(contact)s" % {'alert': alert_html, | |
112 'contact': contact_html} | |
113 self.setHTML(html) | |
114 | |
115 def updateNick(self, new_nick): | |
116 """Change the current nick | |
117 | |
118 @param new_nick(unicode): new nick to use | |
119 """ | |
120 self.nick = new_nick | |
121 self.refresh() | |
122 | |
123 def setAlert(self, alert): | |
124 """Show a visual indicator | |
125 | |
126 @param alert: True if alert must be shown | |
127 """ | |
128 self.alert = alert | |
129 self.refresh() | |
130 | |
131 | |
132 class ContactMenuBar(base_widget.WidgetMenuBar): | |
133 | |
134 def onBrowserEvent(self, event): | |
135 base_widget.WidgetMenuBar.onBrowserEvent(self, event) | |
136 event.stopPropagation() # prevent opening the chat dialog | |
137 | |
138 @classmethod | |
139 def getCategoryHTML(cls, menu_name_i18n, type_): | |
140 return '<img src="%s"/>' % C.DEFAULT_AVATAR_URL | |
141 | |
142 def setUrl(self, url): | |
143 """Set the URL of the contact avatar.""" | |
144 self.items[0].setHTML('<img src="%s" />' % url) | |
145 | |
146 | |
147 class ContactBox(VerticalPanel, ClickHandler, base_widget.DragLabel): | |
148 | |
149 def __init__(self, parent, jid_): | |
150 """ | |
151 @param parent (ContactPanel): ContactPanel hosting this box | |
152 @param jid_ (jid.JID): contact JID | |
153 """ | |
154 VerticalPanel.__init__(self, StyleName='contactBox', VerticalAlignment='middle') | |
155 ClickHandler.__init__(self) | |
156 base_widget.DragLabel.__init__(self, jid_, "CONTACT", parent.host) | |
157 self.jid = jid_.bare | |
158 self.label = ContactLabel(parent.host, self.jid) | |
159 self.avatar = ContactMenuBar(self, parent.host) if parent.handle_menu else Image() | |
160 self.updateAvatar(parent.host.getAvatarURL(self.jid)) | |
161 self.add(self.avatar) | |
162 self.add(self.label) | |
163 self.addClickListener(self) | |
164 | |
165 def addMenus(self, menu_bar): | |
166 menu_bar.addCachedMenus(C.MENU_ROSTER_JID_CONTEXT, {'jid': unicode(self.jid)}) | |
167 menu_bar.addCachedMenus(C.MENU_JID_CONTEXT, {'jid': unicode(self.jid)}) | |
168 | |
169 def setAlert(self, alert): | |
170 """Show a visual indicator | |
171 | |
172 @param alert: True if alert indicator show be shown""" | |
173 self.label.setAlert(alert) | |
174 | |
175 def updateAvatar(self, url): | |
176 """Update the avatar. | |
177 | |
178 @param url (unicode): image url | |
179 """ | |
180 self.avatar.setUrl(url) | |
181 | |
182 def updateNick(self, new_nick): | |
183 """Update the nickname. | |
184 | |
185 @param new_nick (unicode): new nickname to use | |
186 """ | |
187 self.label.updateNick(new_nick) | |
188 | |
189 def onClick(self, sender): | |
190 try: | |
191 self.parent.onClick(self.jid) | |
192 except AttributeError: | |
193 pass | |
194 else: | |
195 self.setAlert(False) | |
196 | 89 |
197 | 90 |
198 class GroupPanel(VerticalPanel): | 91 class GroupPanel(VerticalPanel): |
199 | 92 |
200 def __init__(self, parent): | 93 def __init__(self, parent): |
238 | 131 |
239 def getGroups(self): | 132 def getGroups(self): |
240 return self._groups | 133 return self._groups |
241 | 134 |
242 | 135 |
243 class BaseContactsPanel(VerticalPanel): | 136 class ContactsPanel(base_panels.ContactsPanel): |
244 """ContactList graphic representation | |
245 | |
246 Special features like popup menu panel or changing the contact states must be done in a sub-class. | |
247 """ | |
248 | |
249 def __init__(self, parent, handle_click=True, handle_menu=True): | |
250 """@param on_click (callable): click callback (used if ContactBox is created) | |
251 @param handle_menu (bool): if True, bind a popup menu to the avatar (used if ContactBox is created) | |
252 """ # FIXME | |
253 VerticalPanel.__init__(self) | |
254 self._parent = parent | |
255 self.host = parent.host | |
256 self._contacts = {} # entity jid to ContactBox map | |
257 self.click_listener = None | |
258 self.handle_menu = handle_menu | |
259 | |
260 if handle_click: | |
261 def cb(contact_jid): | |
262 self.host.displayWidget(chat.Chat, contact_jid, type_=C.CHAT_ONE2ONE) | |
263 self.onClick = cb | |
264 | |
265 def display(self, jids): | |
266 """Display a contact in the list. | |
267 | |
268 @param jids (list[jid.JID]): jids to display (the order is kept) | |
269 @param name (unicode): optional name of the contact | |
270 """ | |
271 # FIXME: we do a full clear and add boxes after, we should only remove recently hidden boxes and add new ones, and re-order | |
272 current = [box.jid for box in self.children if isinstance(box, ContactBox)] | |
273 if current == jids: | |
274 # the display doesn't change | |
275 return | |
276 self.clear() | |
277 for jid_ in jids: | |
278 assert isinstance(jid_, jid.JID) | |
279 box = self.getContactBox(jid_) | |
280 VerticalPanel.append(self, box) | |
281 | |
282 def isContactPresent(self, contact_jid): | |
283 """Return True if a contact is present in the panel""" | |
284 return contact_jid in self._contacts | |
285 | |
286 def getContacts(self): | |
287 return self._contacts | |
288 | |
289 def getContactBox(self, contact_jid): | |
290 """get the Contactbox of a contact | |
291 | |
292 if the Contactbox doesn't exists, it will be created | |
293 @param contact_jid (jid.JID): the contact | |
294 @return: ContactBox instance | |
295 """ | |
296 try: | |
297 return self._contacts[contact_jid.bare] | |
298 except KeyError: | |
299 box = ContactBox(self, contact_jid) | |
300 self._contacts[contact_jid.bare] = box | |
301 return box | |
302 | |
303 def updateAvatar(self, jid_, url): | |
304 """Update the avatar of the given contact | |
305 | |
306 @param jid_ (jid.JID): contact jid | |
307 @param url (unicode): image url | |
308 """ | |
309 try: | |
310 self.getContactBox(jid_).updateAvatar(url) | |
311 except TypeError: | |
312 pass | |
313 | |
314 def updateNick(self, jid_, new_nick): | |
315 """Update the avatar of the given contact | |
316 | |
317 @param jid_ (jid.JID): contact jid | |
318 @param new_nick (unicode): new nick of the contact | |
319 """ | |
320 try: | |
321 self.getContactBox(jid_).updateNick(new_nick) | |
322 except TypeError: | |
323 pass | |
324 | |
325 | |
326 class ContactsPanel(BaseContactsPanel): | |
327 """The contact list that is displayed on the left side.""" | 137 """The contact list that is displayed on the left side.""" |
328 | 138 |
329 def __init__(self, parent): | 139 def __init__(self, parent): |
330 BaseContactsPanel.__init__(self, parent, handle_click=True, handle_menu=True) | 140 def on_click(contact_jid): |
141 self.host.displayWidget(chat.Chat, contact_jid, type_=C.CHAT_ONE2ONE) | |
142 base_panels.ContactsPanel.__init__(self, parent, on_click=on_click, handle_menu=True) | |
331 | 143 |
332 def setState(self, jid_, type_, state): | 144 def setState(self, jid_, type_, state): |
333 """Change the appearance of the contact, according to the state | 145 """Change the appearance of the contact, according to the state |
334 | 146 |
335 @param jid_ (jid.JID): jid.JID which need to change state | 147 @param jid_ (jid.JID): jid.JID which need to change state |