plugin XEP-0085, quick_frontends, primitivus: chat states are working again
This commit is contained in:
parent
3a89365ac2
commit
cc160e03d7
7 changed files with 59 additions and 24 deletions
|
|
@ -151,6 +151,10 @@ class OccupantWidget(urwid.WidgetWrap):
|
|||
def __lt__(self, other):
|
||||
return self.occupant_data.nick.lower() < other.occupant_data.nick.lower()
|
||||
|
||||
@property
|
||||
def markup(self):
|
||||
return self._generateMarkup()
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self.mess_data.parent
|
||||
|
|
@ -159,6 +163,10 @@ class OccupantWidget(urwid.WidgetWrap):
|
|||
def nick(self):
|
||||
return self.occupant_data.nick
|
||||
|
||||
def redraw(self):
|
||||
self._w.set_text(self.markup)
|
||||
self.occupant_data.parent.host.redraw() # FIXME: should not be necessary
|
||||
|
||||
def selectable(self):
|
||||
return True
|
||||
|
||||
|
|
@ -181,13 +189,19 @@ class OccupantWidget(urwid.WidgetWrap):
|
|||
# should be more intuitive and themable
|
||||
o = self.occupant_data
|
||||
markup = []
|
||||
markup.append(('info_msg', '{}{} '.format(
|
||||
markup.append(('info_msg', u'{}{} '.format(
|
||||
o.role[0].upper(),
|
||||
o.affiliation[0].upper(),
|
||||
)))
|
||||
markup.append(o.nick)
|
||||
if o.state is not None:
|
||||
markup.append(u' {}'.format(C.CHAT_STATE_ICON[o.state]))
|
||||
return markup
|
||||
|
||||
# events
|
||||
def updated(self, attributes):
|
||||
self.redraw()
|
||||
|
||||
|
||||
class OccupantsWidget(urwid.WidgetWrap):
|
||||
|
||||
|
|
@ -572,6 +586,11 @@ class Chat(PrimitivusWidget, quick_chat.QuickChat):
|
|||
if self.type == C.CHAT_GROUP:
|
||||
self.host.removeListener('presence', self.presenceListener)
|
||||
|
||||
def onChatState(self, from_jid, state, profile):
|
||||
super(Chat, self).onChatState(from_jid, state, profile)
|
||||
if self.type == C.CHAT_ONE2ONE:
|
||||
self.title_dynamic = C.CHAT_STATE_ICON[state]
|
||||
self.host.redraw() # FIXME: should not be necessary
|
||||
|
||||
quick_widgets.register(quick_chat.QuickChat, Chat)
|
||||
quick_widgets.register(quick_games.Tarot, game_tarot.TarotGame)
|
||||
|
|
|
|||
|
|
@ -55,12 +55,13 @@ class Const(constants.Const):
|
|||
# Chats
|
||||
CHAT_ONE2ONE = 'one2one'
|
||||
CHAT_GROUP = 'group'
|
||||
USER_CHAT_STATES = {
|
||||
CHAT_STATE_ICON = {
|
||||
"": u" ",
|
||||
"active": u'✔',
|
||||
"inactive": u'☄',
|
||||
"gone": u'✈',
|
||||
"composing": u'✎',
|
||||
"paused": u"⦷"
|
||||
"paused": u"…"
|
||||
}
|
||||
|
||||
# Blogs
|
||||
|
|
|
|||
|
|
@ -569,20 +569,9 @@ class QuickApp(object):
|
|||
@param state (unicode): new state
|
||||
@param profile (unicode): current profile
|
||||
"""
|
||||
# log.debug(_(u"Received new chat state {} from {} [{}]").format(state, from_jid_s, profile))
|
||||
# from_jid = jid.JID(from_jid_s) if from_jid_s != C.ENTITY_ALL else C.ENTITY_ALL
|
||||
# contact_list = self.contact_lists[profile]
|
||||
# for widget in self.widgets.getWidgets(quick_chat.QuickChat):
|
||||
# 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(widget.target, nick) for nick in widget.occupants]:
|
||||
# contact_list.setCache(occupant, 'chat_state', to_display)
|
||||
# widget.update(occupant)
|
||||
# elif from_jid.bare == widget.target.bare: # roster contact or MUC occupant
|
||||
# contact_list.setCache(from_jid, 'chat_state', to_display)
|
||||
# widget.update(from_jid)
|
||||
from_jid = jid.JID(from_jid_s)
|
||||
for widget in self.widgets.getWidgets(quick_chat.QuickChat, profiles=(profile,)):
|
||||
widget.onChatState(from_jid, state, profile)
|
||||
|
||||
def notify(self, type_, entity=None, message=None, subject=None, callback=None, cb_args=None, widget=None, profile=C.PROF_KEY_NONE):
|
||||
"""Trigger an event notification
|
||||
|
|
|
|||
|
|
@ -126,11 +126,22 @@ class Occupant(object):
|
|||
self.affiliation = data['affiliation']
|
||||
self.role = data['role']
|
||||
self.widgets = set() # widgets linked to this occupant
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
return self.parent.host
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@state.setter
|
||||
def state(self, new_state):
|
||||
self._state = new_state
|
||||
for w in self.widgets:
|
||||
w.updated(["state"])
|
||||
|
||||
|
||||
class QuickChat(quick_widgets.QuickWidget):
|
||||
|
||||
|
|
@ -407,5 +418,17 @@ class QuickChat(quick_widgets.QuickWidget):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
## events ##
|
||||
|
||||
def onChatState(self, from_jid, state, profile):
|
||||
"""A chat state has been received"""
|
||||
if self.type == C.CHAT_GROUP:
|
||||
nick = from_jid.resource
|
||||
try:
|
||||
self.occupants[nick].state = state
|
||||
except KeyError:
|
||||
log.warning(u"{nick} not found in {room}, ignoring new chat state".format(
|
||||
nick=nick, room=self.target.bare))
|
||||
|
||||
|
||||
quick_widgets.register(QuickChat)
|
||||
|
|
|
|||
|
|
@ -79,19 +79,22 @@ class QuickWidgetsManager(object):
|
|||
raise exceptions.InternalError("There is not class registered for {}".format(class_))
|
||||
return cls
|
||||
|
||||
def getWidgets(self, class_):
|
||||
"""Get all subclassed widgets
|
||||
def getWidgets(self, class_, profiles=None):
|
||||
"""Get all subclassed widgets instances
|
||||
|
||||
@param class_: subclass of QuickWidget, same parameter as used in [getOrCreateWidget]
|
||||
@param profiles(iterable, None): if not None, filter on instances linked to these profiles
|
||||
@return: iterator on widgets
|
||||
"""
|
||||
class_ = self.getRealClass(class_)
|
||||
try:
|
||||
widgets_map = self._widgets[class_.__name__]
|
||||
except KeyError:
|
||||
return iter([])
|
||||
return
|
||||
else:
|
||||
return widgets_map.itervalues()
|
||||
for w in widgets_map.itervalues():
|
||||
if profiles is None or w.profiles.intersection(profiles):
|
||||
yield w
|
||||
|
||||
def getWidget(self, class_, target=None, profiles=None):
|
||||
"""Get a widget without creating it if it doesn't exist.
|
||||
|
|
|
|||
|
|
@ -520,7 +520,7 @@ class SAT(service.Service):
|
|||
## XMPP methods ##
|
||||
|
||||
def getWaitingConf(self, profile_key=None):
|
||||
assert(profile_key)
|
||||
assert profile_key
|
||||
client = self.getClient(profile_key)
|
||||
ret = []
|
||||
for conf_id in client._waiting_conf:
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class XEP_0085(object):
|
|||
def __init__(self, host):
|
||||
log.info(_("Chat State Notifications plugin initialization"))
|
||||
self.host = host
|
||||
self.map = {}
|
||||
self.map = {} # FIXME: would be better to use client instead of mapping profile to data
|
||||
|
||||
# parameter value is retrieved before each use
|
||||
host.memory.updateParams(self.params)
|
||||
|
|
@ -141,7 +141,7 @@ class XEP_0085(object):
|
|||
self.host.memory.updateEntityData(entity_jid, ENTITY_KEY, value, profile_key=profile)
|
||||
if not value or value == DELETE_VALUE:
|
||||
# reinit chat state UI for this or these contact(s)
|
||||
self.host.bridge.chatStateReceived(unicode(entity_jid), "", profile)
|
||||
self.host.bridge.chatStateReceived(entity_jid.full(), "", profile)
|
||||
|
||||
def paramUpdateTrigger(self, name, value, category, type_, profile):
|
||||
"""Reset all the existing chat state entity data associated with this profile after a parameter modification.
|
||||
|
|
|
|||
Loading…
Reference in a new issue