Mercurial > libervia-web
view src/browser/sat_browser/contact_panel.py @ 660:267761bf7f08 frontends_multi_profiles
browser side (contact list): ContactPanels is used instead of OccupantsList in MUC:
- ContactPanels become the generic class for all lists of contacts
- OccupantsList will be removed
- need to implements specials icons (e.g. for games) in ContactBox
- ContactBox now manage a display arguments to set which data we want to display
- ContactsPanel.display renamed to setList
- ContactBox style can be changed when instaciating parent ContactsPanel
- muc_contact CSS class is used for list of MUC occupants
Not fully functionnal yet
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 27 Feb 2015 22:53:27 +0100 |
parents | 6d3142b782c3 |
children | 2201ff543a05 |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # Libervia: a Salut à Toi frontend # Copyright (C) 2011, 2012, 2013, 2014 Jérôme Poisson <goffi@goffi.org> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ Contacts / jids related panels """ import pyjd # this is dummy in pyjs from sat.core.log import getLogger log = getLogger(__name__) from sat_frontends.tools import jid from pyjamas.ui.AbsolutePanel import AbsolutePanel from pyjamas.ui.VerticalPanel import VerticalPanel from pyjamas.ui.HTML import HTML import html_tools import contact_widget from constants import Const as C # FIXME: must be removed class Occupant(HTML): """Occupant of a MUC room""" def __init__(self, nick, state=None, special=""): """ @param nick: the user nickname @param state: the user chate state (XEP-0085) @param special: a string of symbols (e.g: for activities) """ HTML.__init__(self, StyleName="occupant") self.nick = nick self._state = state self.special = special self._refresh() def __str__(self): return self.nick def setState(self, state): self._state = state self._refresh() def addSpecial(self, special): """@param special: unicode""" if special not in self.special: self.special += special self._refresh() def removeSpecials(self, special): """@param special: unicode or list""" if not isinstance(special, list): special = [special] for symbol in special: self.special = self.special.replace(symbol, "") self._refresh() def _refresh(self): state = (' %s' % C.MUC_USER_STATES[self._state]) if self._state else '' special = "" if len(self.special) == 0 else " %s" % self.special self.setHTML("%s%s%s" % (html_tools.html_sanitize(self.nick), special, state)) class ContactsPanel(VerticalPanel): """ContactList graphic representation Special features like popup menu panel or changing the contact states must be done in a sub-class. """ def __init__(self, parent, on_click=None, handle_menu=True, contacts_style=None, contacts_display=C.CONTACT_DEFAULT_DISPLAY): """ @param on_click (callable): click callback (used if ContactBox is created) @param handle_menu (bool): if True, bind a popup menu to the avatar (used if ContactBox is created) """ # FIXME VerticalPanel.__init__(self) self._parent = parent self.host = parent.host self._contacts = {} # entity jid to ContactBox map self.click_listener = None self.handle_menu = handle_menu if on_click is not None: self.onClick = on_click self.contacts_style=contacts_style self.contacts_display = contacts_display def setList(self, jids): """set all contacts in the list in one shot. @param jids (list[jid.JID]): jids to display (the order is kept) @param name (unicode): optional name of the contact """ # FIXME: we do a full clear and add boxes after, we should only remove recently hidden boxes and add new ones, and re-order current = [box.jid for box in self.children if isinstance(box, contact_widget.ContactBox)] if current == jids: # 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 def getContactBox(self, contact_jid): """get the Contactbox of a contact if the Contactbox doesn't exists, it will be created @param contact_jid (jid.JID): the contact @return: ContactBox instance """ try: return self._contacts[contact_jid.bare] except KeyError: box = contact_widget.ContactBox(self, contact_jid, style_name=self.contacts_style, display=self.contacts_display) self._contacts[contact_jid.bare] = box return box def updateAvatar(self, jid_, url): """Update the avatar of the given contact @param jid_ (jid.JID): contact jid @param url (unicode): image url """ try: self.getContactBox(jid_).updateAvatar(url) except TypeError: pass def updateNick(self, jid_, new_nick): """Update the avatar of the given contact @param jid_ (jid.JID): contact jid @param new_nick (unicode): new nick of the contact """ try: self.getContactBox(jid_).updateNick(new_nick) except TypeError: pass # FIXME: must be removed and ContactsPanel must be used instead class OccupantsList(AbsolutePanel): """Panel user to show occupants of a room""" def __init__(self): AbsolutePanel.__init__(self) self.occupants_list = {} self.setStyleName('occupantsList') def addOccupant(self, nick): if nick in self.occupants_list: return _occupant = Occupant(nick) self.occupants_list[nick] = _occupant self.add(_occupant) def removeOccupant(self, nick): try: self.remove(self.occupants_list[nick]) except KeyError: log.error("trying to remove an unexisting nick") def getOccupantBox(self, nick): """Get the widget element of the given nick. @return: Occupant """ try: return self.occupants_list[nick] except KeyError: return None def clear(self): self.occupants_list.clear() AbsolutePanel.clear(self) def updateSpecials(self, occupants=[], html=""): """Set the specified html "symbol" to the listed occupants, and eventually remove it from the others (if they got it). This is used for example to visualize who is playing a game. @param occupants: list of the occupants that need the symbol @param html: unicode symbol (actually one character or more) or a list to assign different symbols of the same family. """ index = 0 special = html for occupant in self.occupants_list.keys(): if occupant in occupants: if isinstance(html, list): special = html[index] index = (index + 1) % len(html) self.occupants_list[occupant].addSpecial(special) else: self.occupants_list[occupant].removeSpecials(html)