quick_frontends, primitivus: move the chat states logic to quick_frontend
This commit is contained in:
parent
c6419871ac
commit
14f4b4b8ec
5 changed files with 70 additions and 35 deletions
|
|
@ -150,25 +150,29 @@ class Chat(PrimitivusWidget, QuickChat):
|
|||
menu.addMenu(_("Action"), _("Send file"), self.onSendFileRequest)
|
||||
return menu
|
||||
|
||||
def updateChatState(self, from_jid, state):
|
||||
if self.type == C.CHAT_GROUP:
|
||||
if from_jid == C.ENTITY_ALL:
|
||||
occupants = self.occupants
|
||||
else:
|
||||
nick = from_jid.resource
|
||||
if not nick:
|
||||
log.debug("no nick found for chatstate")
|
||||
return
|
||||
occupants = [nick]
|
||||
options = self.present_wid.getAllValues()
|
||||
for index in xrange(0, len(options)):
|
||||
nick = options[index].value
|
||||
if nick in occupants:
|
||||
options[index] = (nick, '%s %s' % (C.MUC_USER_STATES[state], nick))
|
||||
self.present_wid.changeValues(options)
|
||||
self.host.redraw()
|
||||
else:
|
||||
self.title_dynamic = '({})'.format(state)
|
||||
def setOccupantStates(self, occupant_jid, states):
|
||||
"""Set a MUC occupant's states.
|
||||
|
||||
@param occupant_jid (jid.JID): occupant to update
|
||||
@param states (dict{unicode: unicode}): new states
|
||||
"""
|
||||
options = self.present_wid.getAllValues()
|
||||
for index in xrange(0, len(options)):
|
||||
nick = options[index].value
|
||||
if nick == occupant_jid.resource:
|
||||
options[index] = (nick, "%s %s" % (u''.join(states.values()), nick))
|
||||
self.present_wid.changeValues(options)
|
||||
break
|
||||
self.host.redraw()
|
||||
|
||||
def setContactStates(self, contact_jid, states):
|
||||
"""Set a one2one contact's states.
|
||||
|
||||
@param contact_jid (jid.JID): contact
|
||||
@param states (dict{unicode: unicode}): new states
|
||||
"""
|
||||
self.title_dynamic = ' '.join([u'({})'.format(state) for state in states.values()])
|
||||
self.host.redraw()
|
||||
|
||||
def _presentClicked(self, list_wid, clicked_wid):
|
||||
assert self.type == C.CHAT_GROUP
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ class Const(constants.Const):
|
|||
XMLUI_STATUS_CANCELLED = constants.Const.XMLUI_DATA_CANCELLED
|
||||
|
||||
# MUC
|
||||
ALL_OCCUPANTS = 1
|
||||
MUC_USER_STATES = {
|
||||
USER_CHAT_STATES = {
|
||||
"active": u'✔',
|
||||
"inactive": u'☄',
|
||||
"gone": u'✈',
|
||||
|
|
|
|||
|
|
@ -574,16 +574,22 @@ class QuickApp(object):
|
|||
log.debug("new subject for room [%(room_jid)s]: %(subject)s" % {'room_jid': room_jid, "subject": subject})
|
||||
|
||||
def chatStateReceivedHandler(self, from_jid_s, state, profile):
|
||||
"""Called when a new chat state is received.
|
||||
"""Called when a new chat state (XEP-0085) is received.
|
||||
|
||||
@param from_jid_s: JID of the contact who sent his state, or '@ALL@'
|
||||
@param state: new state (string)
|
||||
@profile: current profile
|
||||
@param from_jid_s (unicode): JID of a contact or C.ENTITY_ALL
|
||||
@param state (unicode): new state
|
||||
@param profile (unicode): current profile
|
||||
"""
|
||||
from_jid = jid.JID(from_jid_s) if from_jid_s != C.ENTITY_ALL else C.ENTITY_ALL
|
||||
for widget in self.widgets.getWidgets(quick_chat.QuickChat):
|
||||
if from_jid == C.ENTITY_ALL or from_jid.bare == widget.target.bare:
|
||||
widget.updateChatState(from_jid, state)
|
||||
if profile != widget.profile:
|
||||
continue
|
||||
to_display = C.USER_CHAT_STATES[state] if (state and widget.type == C.CHAT_GROUP) else state
|
||||
if widget.type == C.CHAT_GROUP and from_jid_s == C.ENTITY_ALL:
|
||||
for occupant in [jid.newResource(self.target, nick) for nick in widget.occupants]:
|
||||
widget.updateEntityState(occupant, 'chat_state', to_display)
|
||||
elif from_jid.bare == widget.target.bare: # roster contact or MUC occupant
|
||||
widget.updateEntityState(from_jid, 'chat_state', to_display)
|
||||
|
||||
def personalEventHandler(self, sender, event_type, data):
|
||||
"""Called when a PEP event is received.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ log = getLogger(__name__)
|
|||
from sat_frontends.tools import jid
|
||||
from sat_frontends.quick_frontend import quick_widgets
|
||||
from sat_frontends.quick_frontend.constants import Const as C
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
try:
|
||||
# FIXME: to be removed when an acceptable solution is here
|
||||
|
|
@ -34,6 +34,8 @@ except (TypeError, AttributeError): # Error raised is not the same depending on
|
|||
|
||||
class QuickChat(quick_widgets.QuickWidget):
|
||||
|
||||
visible_states = ['chat_state']
|
||||
|
||||
def __init__(self, host, target, type_=C.CHAT_ONE2ONE, profiles=None):
|
||||
"""
|
||||
@param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for chat à la IRC
|
||||
|
|
@ -207,12 +209,25 @@ class QuickChat(quick_widgets.QuickWidget):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def updateChatState(self, from_jid, state):
|
||||
"""Set the chat state (XEP-0085) of the contact.
|
||||
def updateEntityState(self, entity, type_, value):
|
||||
"""Update a state value for the given entity.
|
||||
|
||||
@param state: the new chat state
|
||||
@param entity (jid.JID): entity to update
|
||||
@param type_ (unicode): type of state (e.g. 'chat_state')
|
||||
@param value (unicode): new value
|
||||
"""
|
||||
raise NotImplementedError
|
||||
contact_list = self.host.contact_lists[self.profile]
|
||||
contact_list.setCache(entity, type_, value)
|
||||
clist = self.host.contact_lists[self.profile]
|
||||
states = OrderedDict()
|
||||
for key in self.visible_states:
|
||||
value = clist.getCache(entity, key)
|
||||
if value:
|
||||
states[key] = value
|
||||
if self.type == C.CHAT_GROUP:
|
||||
self.setOccupantStates(entity, states)
|
||||
else:
|
||||
self.setContactStates(entity, states)
|
||||
|
||||
def addGamePanel(self, widget):
|
||||
"""Insert a game panel to this Chat dialog.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
# hack to use this module with pyjamas
|
||||
try:
|
||||
unicode('') # XXX: unicode doesn't exist in pyjamas
|
||||
unicode('') # XXX: unicode doesn't exist in pyjamas
|
||||
|
||||
# normal version
|
||||
class BaseJID(unicode):
|
||||
|
|
@ -38,14 +38,15 @@ try:
|
|||
node_end = 0
|
||||
domain_end = self.find('/')
|
||||
if domain_end == 0:
|
||||
raise ValueError("a jid can't start with '/'")
|
||||
raise ValueError("a jid can't start with '/'")
|
||||
if domain_end == -1:
|
||||
domain_end = len(self)
|
||||
self.node = self[:node_end] or None
|
||||
self.domain = self[(node_end + 1) if node_end else 0:domain_end]
|
||||
self.resource = self[domain_end + 1:] or None
|
||||
|
||||
except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options
|
||||
except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options
|
||||
|
||||
# pyjamas version
|
||||
class BaseJID(object):
|
||||
def __init__(self, jid_str):
|
||||
|
|
@ -113,3 +114,13 @@ class JID(BaseJID):
|
|||
"""
|
||||
# TODO: implement real check, according to the RFC http://tools.ietf.org/html/rfc6122
|
||||
return self.domain != ""
|
||||
|
||||
|
||||
def newResource(entity, resource):
|
||||
"""Build a new JID from the given entity and resource.
|
||||
|
||||
@param entity (JID): original JID
|
||||
@param resource (unicode): new resource
|
||||
@return: a new JID instance
|
||||
"""
|
||||
return JID(u"%s/%s" % (entity.bare, resource))
|
||||
|
|
|
|||
Loading…
Reference in a new issue