# HG changeset patch # User souliane # Date 1426096887 -3600 # Node ID e489218886d7ebac380ec65534fd5ad593163e6b # Parent b39a9eddfe5646a74743f54015a06b3b65235bc7 browser_side: add attribute "merge_resources" to ContactsPanel to display the MUC occupants + override Chat.replaceUser and Chat.removeUser diff -r b39a9eddfe56 -r e489218886d7 src/browser/public/libervia.css --- a/src/browser/public/libervia.css Wed Mar 11 12:50:19 2015 +0100 +++ b/src/browser/public/libervia.css Wed Mar 11 19:01:27 2015 +0100 @@ -1035,10 +1035,9 @@ white-space: nowrap; } -.occupantsPanel { +.occupantsPanelCell { border-right: 2px dotted #ddd; - margin-left: 5px; - margin-right: 10px; + padding-left: 5px; height: 100%; } diff -r b39a9eddfe56 -r e489218886d7 src/browser/sat_browser/chat.py --- a/src/browser/sat_browser/chat.py Wed Mar 11 12:50:19 2015 +0100 +++ b/src/browser/sat_browser/chat.py Wed Mar 11 19:01:27 2015 +0100 @@ -34,6 +34,7 @@ from pyjamas.ui.HTML import HTML from pyjamas.ui.KeyboardListener import KEY_ENTER, KeyboardHandler from pyjamas.ui.HTMLPanel import HTMLPanel +from pyjamas import DOM from datetime import datetime from time import time @@ -96,12 +97,12 @@ chat_area = HorizontalPanel() chat_area.setStyleName('chatArea') if type_ == C.CHAT_GROUP: - self.occupants_panel = contact_panel.ContactsPanel(host, + self.occupants_panel = contact_panel.ContactsPanel(host, merge_resources=False, contacts_style="muc_contact", contacts_menus=(C.MENU_JID_CONTEXT), contacts_display=('resource',)) - self.occupants_panel.setStyleName("occupantsPanel") chat_area.add(self.occupants_panel) + DOM.setAttribute(chat_area.getWidgetTd(self.occupants_panel), "className", "occupantsPanelCell") self._body.add(chat_area) self.content = AbsolutePanel() self.content.setStyleName('chatContent') @@ -204,21 +205,24 @@ self.nick = nick def setPresents(self, nicks): - """Set the users presents in this room - @param occupants (list[unicode]): list of nicks + """Set the occupants of a group chat. + + @param nicks (list[unicode]): sorted list of nicknames """ - self.occupants_panel.setList([jid.JID(u"%s/%s" % (self.target,nick)) for nick in nicks]) + QuickChat.setPresents(self, nicks) + self.occupants_panel.setList([jid.JID(u"%s/%s" % (self.target, nick)) for nick in nicks]) - # def userJoined(self, nick, data): - # if self.occupants_panel.getOccupantBox(nick): - # return # user is already displayed - # self.occupants_panel.addOccupant(nick) - # if self.occupants_initialised: - # self.printInfo("=> %s has joined the room" % nick) + def replaceUser(self, nick, show_info=True): + """Add user if it is not in the group list""" + QuickChat.replaceUser(self, nick, show_info) + occupant_jid = jid.JID("%s/%s" % (unicode(self.target), nick)) + self.occupants_panel.addContact(occupant_jid) - # def userLeft(self, nick, data): - # self.occupants_panel.removeOccupant(nick) - # self.printInfo("<= %s has left the room" % nick) + def removeUser(self, nick, show_info=True): + """Remove a user from the group list""" + QuickChat.removeUser(self, nick, show_info) + occupant_jid = jid.JID("%s/%s" % (unicode(self.target), nick)) + self.occupants_panel.removeContact(occupant_jid) def changeUserNick(self, old_nick, new_nick): assert self.type == C.CHAT_GROUP diff -r b39a9eddfe56 -r e489218886d7 src/browser/sat_browser/contact_list.py --- a/src/browser/sat_browser/contact_list.py Wed Mar 11 12:50:19 2015 +0100 +++ b/src/browser/sat_browser/contact_list.py Wed Mar 11 19:01:27 2015 +0100 @@ -409,7 +409,7 @@ @param group (unicode): the group to check @return: boolean """ - raise Exception # FIXME: remove this method + raise Exception # FIXME: remove this method for jid_ in self.groups[group]: if self._contacts_panel.getContactBox(jid_).isVisible(): return True @@ -434,7 +434,7 @@ entity_bare = entity.bare show = self.getCache(entity_bare, C.PRESENCE_SHOW) # we use cache to have the show nformation of main resource only self._contacts_panel.setState(entity_bare, "availability", show) - self.update() + self.update() # FIXME: should update the list without rebuilding it all # def updateVisibility(self, jids, groups): # """Set the widgets visibility for the given contacts and groups diff -r b39a9eddfe56 -r e489218886d7 src/browser/sat_browser/contact_panel.py --- a/src/browser/sat_browser/contact_panel.py Wed Mar 11 12:50:19 2015 +0100 +++ b/src/browser/sat_browser/contact_panel.py Wed Mar 11 19:01:27 2015 +0100 @@ -82,10 +82,14 @@ Special features like popup menu panel or changing the contact states must be done in a sub-class. """ - def __init__(self, host, contacts_click=None, contacts_style=None, contacts_menus=True, contacts_display=C.CONTACT_DEFAULT_DISPLAY): + def __init__(self, host, merge_resources=True, contacts_click=None, + contacts_style=None, contacts_menus=True, + contacts_display=C.CONTACT_DEFAULT_DISPLAY): """ @param host (SatWebFrontend): host instance + @param merge_resources (bool): if True, the entities sharing the same + bare JID will also share the same contact box. @param contacts_click (callable): click callback for the contact boxes @param contacts_style (unicode): CSS style name for the contact boxes @param contacts_menus (tuple): define the menu types that fit this @@ -95,6 +99,7 @@ """ VerticalPanel.__init__(self) self.host = host + self.merge_resources = merge_resources self._contacts = {} # entity jid to ContactBox map self.click_listener = None @@ -105,6 +110,14 @@ self.contacts_menus = contacts_menus self.contacts_display = contacts_display + def _key(self, contact_jid): + """Return internal key for this contact. + + @param contact_jid (jid.JID): contact JID + @return: jid.JID + """ + return contact_jid.bare if self.merge_resources else contact_jid + def setList(self, jids): """set all contacts in the list in one shot. @@ -117,54 +130,62 @@ # the display doesn't change return self.clear() - for jid_ in jids: - assert isinstance(jid_, jid.JID) - box = self.getContactBox(jid_) - VerticalPanel.append(self, box) - - def isContactPresent(self, contact_jid): - """Return True if a contact is present in the panel""" - return contact_jid in self._contacts - - def getContacts(self): - return self._contacts + for contact_jid in jids: + assert isinstance(contact_jid, jid.JID) + self.addContact(contact_jid) def getContactBox(self, contact_jid): - """get the Contactbox of a contact + """Get a contact box for a contact, add it if it doesn't exist yet. - if the Contactbox doesn't exists, it will be created - @param contact_jid (jid.JID): the contact - @return: ContactBox instance + @param contact_jid (jid.JID): contact JID + @return: ContactBox """ try: - return self._contacts[contact_jid.bare] + return self._contacts[self._key(contact_jid)] except KeyError: box = contact_widget.ContactBox(self.host, contact_jid, style_name=self.contacts_style, menu_types=self.contacts_menus, display=self.contacts_display) - self._contacts[contact_jid.bare] = box + self._contacts[self._key(contact_jid)] = box return box - def updateAvatar(self, jid_, url): + def addContact(self, contact_jid): + """Add a contact to the list. + + @param contact_jid (jid.JID): contact JID + """ + box = self.getContactBox(contact_jid) + if box not in self.children: + VerticalPanel.append(self, box) + + def removeContact(self, contact_jid): + """Remove a contact from the list. + + @param contact_jid (jid.JID): contact JID + """ + box = self._contacts.pop(self._key(contact_jid)) + VerticalPanel.remove(self, box) + + def updateAvatar(self, contact_jid, url): """Update the avatar of the given contact - @param jid_ (jid.JID): contact jid + @param contact_jid (jid.JID): contact JID @param url (unicode): image url """ try: - self.getContactBox(jid_).updateAvatar(url) + self.getContactBox(contact_jid).updateAvatar(url) except TypeError: pass - def updateNick(self, jid_, new_nick): - """Update the avatar of the given contact + def updateNick(self, contact_jid, new_nick): + """Update the avatar of the given contact. - @param jid_ (jid.JID): contact jid + @param contact_jid (jid.JID): contact JID @param new_nick (unicode): new nick of the contact """ try: - self.getContactBox(jid_).updateNick(new_nick) + self.getContactBox(contact_jid).updateNick(new_nick) except TypeError: pass