Mercurial > libervia-web
comparison browser_side/panels.py @ 230:266e9678eec0
browser_side: added the flag REUSE_EXISTING_LIBERVIA_WIDGETS
- do not create a new chat panel for contacts/groups if a similar one is found in the same tab
- this goes with a modification of the methods to create new panels, especially arguments handling
- improvement of the accepted groups list for MicroblogPanel (remove duplicates and keep sorted)
Details for the new flag:
# Set to true to not create a new LiberviaWidget when a similar one
# already exist (i.e. a chat panel with the same target). Instead
# the existing widget will be eventually removed from its parent
# and added to new WidgetsPanel, or replaced to the expected
# position if the previous and the new parent are the same.
author | souliane <souliane@mailoo.org> |
---|---|
date | Tue, 08 Oct 2013 13:57:35 +0200 |
parents | 744426c2b699 |
children | fab7aa366576 |
comparison
equal
deleted
inserted
replaced
229:e632f77c4219 | 230:266e9678eec0 |
---|---|
299 | 299 |
300 def __init__(self, host, accepted_groups): | 300 def __init__(self, host, accepted_groups): |
301 """Panel used to show microblog | 301 """Panel used to show microblog |
302 @param accepted_groups: groups displayed in this panel, if empty, show all microblogs from all contacts | 302 @param accepted_groups: groups displayed in this panel, if empty, show all microblogs from all contacts |
303 """ | 303 """ |
304 base_widget.LiberviaWidget.__init__(self, host, ", ".join(accepted_groups), selectable = True) | 304 base_widget.LiberviaWidget.__init__(self, host, ", ".join(accepted_groups), selectable=True) |
305 #base_widget.ScrollPanelWrapper.__init__(self) | 305 self.setAcceptedGroup(accepted_groups) |
306 #DropCell.__init__(self) | |
307 self.accepted_groups = accepted_groups | |
308 self.entries = {} | 306 self.entries = {} |
309 self.comments = {} | 307 self.comments = {} |
310 self.selected_entry = None | 308 self.selected_entry = None |
311 self.vpanel = VerticalPanel() | 309 self.vpanel = VerticalPanel() |
312 self.vpanel.setStyleName('microblogPanel') | 310 self.vpanel.setStyleName('microblogPanel') |
313 self.setWidget(self.vpanel) | 311 self.setWidget(self.vpanel) |
314 | 312 |
315 @classmethod | 313 @classmethod |
316 def registerClass(cls): | 314 def registerClass(cls): |
317 base_widget.LiberviaWidget.addDropKey("GROUP", cls.createGroup) | 315 base_widget.LiberviaWidget.addDropKey("GROUP", cls.createPanel) |
318 base_widget.LiberviaWidget.addDropKey("CONTACT_TITLE", cls.createMeta) | 316 base_widget.LiberviaWidget.addDropKey("CONTACT_TITLE", cls.createMetaPanel) |
319 | 317 |
320 @classmethod | 318 @classmethod |
321 def createGroup(cls, host, item): | 319 def createPanel(cls, host, item): |
322 _new_panel = MicroblogPanel(host, [item]) #XXX: pyjamas doesn't support use of cls directly | 320 """Generic panel creation for one, several or all groups (meta). |
323 _new_panel.setAcceptedGroup(item) | 321 @parem host: the SatWebFrontend instance |
322 @param item: single group as a string, list of groups | |
323 (as an array) or None (for the meta group = "all groups") | |
324 @return: the created MicroblogPanel | |
325 """ | |
326 _items = item if isinstance(item, list) else ([] if item is None else [item]) | |
327 _type = 'ALL' if _items == [] else 'GROUP' | |
328 # XXX: pyjamas doesn't support use of cls directly | |
329 _new_panel = MicroblogPanel(host, _items) | |
324 host.FillMicroblogPanel(_new_panel) | 330 host.FillMicroblogPanel(_new_panel) |
325 host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, 'GROUP', [item], 10) | 331 host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, _type, _items, 10) |
332 host.setSelected(_new_panel) | |
326 return _new_panel | 333 return _new_panel |
327 | 334 |
328 @classmethod | 335 @classmethod |
329 def createMeta(cls, host, item): | 336 def createMetaPanel(cls, host, item): |
330 _new_panel = MicroblogPanel(host, []) #XXX: pyjamas doesn't support use of cls directly | 337 """Needed for the drop keys to not be mixed between meta panel and panel for "Contacts" group""" |
331 host.FillMicroblogPanel(_new_panel) | 338 return MicroblogPanel.createPanel(host, None) |
332 host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, 'ALL', [], 10) | 339 |
333 return _new_panel | 340 @property |
341 def accepted_groups(self): | |
342 return self._accepted_groups | |
343 | |
344 def matchEntity(self, entity): | |
345 """ | |
346 @param entity: single group as a string, list of groups | |
347 (as an array) or None (for the meta group = "all groups") | |
348 @return: True if self matches the given entity | |
349 """ | |
350 entity = entity if isinstance(entity, list) else ([] if entity is None else [entity]) | |
351 entity.sort() # sort() do not return the sorted list: do it here, not on the "return" line | |
352 return self.accepted_groups == entity | |
334 | 353 |
335 def getWarningData(self): | 354 def getWarningData(self): |
336 if self.selected_entry: | 355 if self.selected_entry: |
337 if not self.selected_entry.comments: | 356 if not self.selected_entry.comments: |
338 print ("ERROR: an item without comment is selected") | 357 print ("ERROR: an item without comment is selected") |
339 return ("NONE", None) | 358 return ("NONE", None) |
340 return ("PUBLIC", "This is a <span class='warningTarget'>comment</span> and keep the initial post visibility, so it is potentialy public") | 359 return ("PUBLIC", "This is a <span class='warningTarget'>comment</span> and keep the initial post visibility, so it is potentialy public") |
341 | 360 |
342 elif not self.accepted_groups: | 361 elif not self._accepted_groups: |
343 # we have a meta MicroblogPanel, we publish publicly | 362 # we have a meta MicroblogPanel, we publish publicly |
344 return ("PUBLIC", self.warning_msg_public) | 363 return ("PUBLIC", self.warning_msg_public) |
345 else: | 364 else: |
346 # we only accept one group at the moment | 365 # we only accept one group at the moment |
347 # FIXME: manage several groups | 366 # FIXME: manage several groups |
348 return ("GROUP", self.warning_msg_group % self.accepted_groups[0]) | 367 return ("GROUP", self.warning_msg_group % self._accepted_groups[0]) |
349 | 368 |
350 def onTextEntered(self, text): | 369 def onTextEntered(self, text): |
351 if self.selected_entry: | 370 if self.selected_entry: |
352 # we are entering a comment | 371 # we are entering a comment |
353 comments_node = self.selected_entry.comments | 372 comments_node = self.selected_entry.comments |
354 if not comments_node: | 373 if not comments_node: |
355 raise Exception("ERROR: comments node is empty") | 374 raise Exception("ERROR: comments node is empty") |
356 self.host.bridge.call("sendMblogComment", None, comments_node, text) | 375 self.host.bridge.call("sendMblogComment", None, comments_node, text) |
357 elif not self.accepted_groups: | 376 elif not self._accepted_groups: |
358 # we are entering a public microblog | 377 # we are entering a public microblog |
359 self.host.bridge.call("sendMblog", None, "PUBLIC", None, text) | 378 self.host.bridge.call("sendMblog", None, "PUBLIC", None, text) |
360 else: | 379 else: |
361 # we are entering a microblog restricted to a group | 380 # we are entering a microblog restricted to a group |
362 # FIXME: manage several groups | 381 # FIXME: manage several groups |
363 self.host.bridge.call("sendMblog", None, "GROUP", self.accepted_groups[0], text) | 382 self.host.bridge.call("sendMblog", None, "GROUP", self._accepted_groups[0], text) |
364 | 383 |
365 def accept_all(self): | 384 def accept_all(self): |
366 return not self.accepted_groups #we accept every microblog only if we are not filtering by groups | 385 return not self._accepted_groups # we accept every microblog only if we are not filtering by groups |
367 | 386 |
368 def getEntries(self): | 387 def getEntries(self): |
369 """Ask all the entries for the currenly accepted groups, | 388 """Ask all the entries for the currenly accepted groups, |
370 and fill the panel""" | 389 and fill the panel""" |
371 | 390 |
479 updateVPanel(child) | 498 updateVPanel(child) |
480 if type == 'avatar': | 499 if type == 'avatar': |
481 updateVPanel(self.vpanel) | 500 updateVPanel(self.vpanel) |
482 | 501 |
483 def setAcceptedGroup(self, group): | 502 def setAcceptedGroup(self, group): |
484 """Set the group which can be displayed in this panel | 503 """Add one or more group(s) which can be displayed in this panel. |
504 Prevent from duplicate values and keep the list sorted. | |
485 @param group: string of the group, or list of string | 505 @param group: string of the group, or list of string |
486 """ | 506 """ |
487 if isinstance(group, list): | 507 if not hasattr(self, "_accepted_groups"): |
488 self.accepted_groups.extend(group) | 508 self._accepted_groups = [] |
489 else: | 509 groups = group if isinstance(group, list) else [group] |
490 self.accepted_groups.append(group) | 510 for _group in groups: |
511 if _group not in self._accepted_groups: | |
512 self._accepted_groups.append(_group) | |
513 self._accepted_groups.sort() | |
491 | 514 |
492 def isJidAccepted(self, jid): | 515 def isJidAccepted(self, jid): |
493 """Tell if a jid is actepted and shown in this panel | 516 """Tell if a jid is actepted and shown in this panel |
494 @param jid: jid | 517 @param jid: jid |
495 @return: True if the jid is accepted""" | 518 @return: True if the jid is accepted""" |
496 if self.accept_all(): | 519 if self.accept_all(): |
497 return True | 520 return True |
498 for group in self.accepted_groups: | 521 for group in self._accepted_groups: |
499 if self.host.contact_panel.isContactInGroup(group, jid): | 522 if self.host.contact_panel.isContactInGroup(group, jid): |
500 return True | 523 return True |
501 return False | 524 return False |
502 | 525 |
503 | 526 |
617 #the event will not propagate to children | 640 #the event will not propagate to children |
618 base_widget.ScrollPanelWrapper.doAttachChildren(self)""" | 641 base_widget.ScrollPanelWrapper.doAttachChildren(self)""" |
619 | 642 |
620 @classmethod | 643 @classmethod |
621 def registerClass(cls): | 644 def registerClass(cls): |
622 base_widget.LiberviaWidget.addDropKey("CONTACT", cls.createChat) | 645 base_widget.LiberviaWidget.addDropKey("CONTACT", cls.createPanel) |
623 | 646 |
624 @classmethod | 647 @classmethod |
625 def createChat(cls, host, item): | 648 def createPanel(cls, host, item): |
626 _contact = JID(item) | 649 _contact = item if isinstance(item, JID) else JID(item) |
627 host.contact_panel.setContactMessageWaiting(_contact.bare, False) | 650 host.contact_panel.setContactMessageWaiting(_contact.bare, False) |
628 _new_panel = ChatPanel(host, _contact) # XXX: pyjamas doesn't seems to support creating with cls directly | 651 _new_panel = ChatPanel(host, _contact) # XXX: pyjamas doesn't seems to support creating with cls directly |
629 _new_panel.historyPrint() | 652 _new_panel.historyPrint() |
653 host.setSelected(_new_panel) | |
630 return _new_panel | 654 return _new_panel |
655 | |
656 def refresh(self): | |
657 """Refresh the display of this widget.""" | |
658 self.host.contact_panel.setContactMessageWaiting(self.target.bare, False) | |
659 self.content_scroll.scrollToBottom() | |
660 | |
661 def matchEntity(self, entity): | |
662 """ | |
663 @param entity: target jid as a string or JID instance | |
664 @return: True if self matches the given entity | |
665 """ | |
666 entity = entity if isinstance(entity, JID) else JID(entity) | |
667 try: | |
668 return self.target.bare == entity.bare | |
669 except AttributeError as e: | |
670 e.include_traceback() | |
671 return False | |
631 | 672 |
632 def getWarningData(self): | 673 def getWarningData(self): |
633 if self.type not in ["one2one", "group"]: | 674 if self.type not in ["one2one", "group"]: |
634 raise Exception("Unmanaged type !") | 675 raise Exception("Unmanaged type !") |
635 if self.type == "one2one": | 676 if self.type == "one2one": |