[Geobert] JEP-0022 partial support (composing). Tunned by me. Fixes #1317
This commit is contained in:
parent
03ce89fdac
commit
4b327b5682
5 changed files with 39 additions and 26 deletions
|
@ -337,14 +337,14 @@ class ChatControlBase(MessageControl):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send_message(self, message, keyID = '', type = 'chat', chatstate = None):
|
def send_message(self, message, keyID = '', type = 'chat', chatstate = None, msg_id = None):
|
||||||
'''Send the given message to the active tab'''
|
'''Send the given message to the active tab'''
|
||||||
if not message or message == '\n':
|
if not message or message == '\n':
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self._process_command(message):
|
if not self._process_command(message):
|
||||||
MessageControl.send_message(self, message, keyID, type = type,
|
MessageControl.send_message(self, message, keyID, type = type,
|
||||||
chatstate = chatstate)
|
chatstate = chatstate, msg_id = msg_id)
|
||||||
# Record message history
|
# Record message history
|
||||||
self.save_sent_message(message)
|
self.save_sent_message(message)
|
||||||
|
|
||||||
|
@ -974,7 +974,7 @@ class ChatControl(ChatControlBase):
|
||||||
self._schedule_activity_timers()
|
self._schedule_activity_timers()
|
||||||
|
|
||||||
ChatControlBase.send_message(self, message, keyID, type = 'chat',
|
ChatControlBase.send_message(self, message, keyID, type = 'chat',
|
||||||
chatstate = chatstate_to_send)
|
chatstate = chatstate_to_send, msg_id = contact.msg_id)
|
||||||
self.print_conversation(message, self.contact.jid, encrypted = encrypted)
|
self.print_conversation(message, self.contact.jid, encrypted = encrypted)
|
||||||
|
|
||||||
def check_for_possible_paused_chatstate(self, arg):
|
def check_for_possible_paused_chatstate(self, arg):
|
||||||
|
|
|
@ -388,23 +388,20 @@ class Connection:
|
||||||
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
||||||
encrypted = False
|
encrypted = False
|
||||||
chatstate = None
|
chatstate = None
|
||||||
xtags = msg.getTags('x')
|
encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED)
|
||||||
encTag = None
|
|
||||||
decmsg = ''
|
decmsg = ''
|
||||||
invite = None
|
|
||||||
delayed = False
|
|
||||||
for xtag in xtags:
|
|
||||||
if xtag.getNamespace() == common.xmpp.NS_ENCRYPTED:
|
|
||||||
encTag = xtag
|
|
||||||
# invitations
|
# invitations
|
||||||
elif xtag.getNamespace() == common.xmpp.NS_MUC_USER and \
|
invite = None
|
||||||
xtag.getTag('invite') and not encTag:
|
if not encTag:
|
||||||
invite = xtag
|
invite = msg.getTag('x', namespace = common.xmpp.NS_MUC_USER)
|
||||||
elif xtag.getNamespace() == common.xmpp.NS_DELAY:
|
if invite and not invite.getTag('invite'):
|
||||||
delayed = True
|
invite = None
|
||||||
|
delayed = msg.getTag('x', namespace = common.xmpp.NS_DELAY) != None
|
||||||
|
msg_id = None
|
||||||
# FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED
|
# FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED
|
||||||
# invitation
|
# invitation
|
||||||
# stanza (MUC JEP) remove in 2007, as we do not do NOT RECOMMENDED
|
# stanza (MUC JEP) remove in 2007, as we do not do NOT RECOMMENDED
|
||||||
|
xtags = msg.getTags('x')
|
||||||
for xtag in xtags:
|
for xtag in xtags:
|
||||||
if xtag.getNamespace() == common.xmpp.NS_CONFERENCE and not invite:
|
if xtag.getNamespace() == common.xmpp.NS_CONFERENCE and not invite:
|
||||||
room_jid = xtag.getAttr('jid')
|
room_jid = xtag.getAttr('jid')
|
||||||
|
@ -417,6 +414,12 @@ class Connection:
|
||||||
if child.getNamespace() == 'http://jabber.org/protocol/chatstates':
|
if child.getNamespace() == 'http://jabber.org/protocol/chatstates':
|
||||||
chatstate = child.getName()
|
chatstate = child.getName()
|
||||||
break
|
break
|
||||||
|
# No JEP-0085 support, fallback to JEP-0022
|
||||||
|
if not chatstate:
|
||||||
|
chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT)
|
||||||
|
chatstate = 'active'
|
||||||
|
if not msgtxt and chatstate_child.getTag('composing'):
|
||||||
|
chatstate = 'composing'
|
||||||
|
|
||||||
if encTag and USE_GPG:
|
if encTag and USE_GPG:
|
||||||
#decrypt
|
#decrypt
|
||||||
|
@ -452,7 +455,7 @@ class Connection:
|
||||||
no_log_for:
|
no_log_for:
|
||||||
gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
||||||
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject,
|
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject,
|
||||||
chatstate))
|
chatstate, msg_id))
|
||||||
else: # it's single message
|
else: # it's single message
|
||||||
if self.name not in no_log_for and jid not in no_log_for:
|
if self.name not in no_log_for and jid not in no_log_for:
|
||||||
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim, subject = subject)
|
||||||
|
@ -465,7 +468,7 @@ class Connection:
|
||||||
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password))
|
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password))
|
||||||
else:
|
else:
|
||||||
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, 'normal',
|
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, 'normal',
|
||||||
subject, None))
|
subject, chatstate, msg_id))
|
||||||
# END messageCB
|
# END messageCB
|
||||||
|
|
||||||
def _presenceCB(self, con, prs):
|
def _presenceCB(self, con, prs):
|
||||||
|
@ -2105,7 +2108,7 @@ class Connection:
|
||||||
msg_iq = common.xmpp.Message(to = jid, body = msg, subject = subject)
|
msg_iq = common.xmpp.Message(to = jid, body = msg, subject = subject)
|
||||||
self.connection.send(msg_iq)
|
self.connection.send(msg_iq)
|
||||||
|
|
||||||
def send_message(self, jid, msg, keyID, type = 'chat', subject='', chatstate = None):
|
def send_message(self, jid, msg, keyID, type = 'chat', subject='', chatstate = None, msg_id = None):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
if not msg and chatstate is None:
|
if not msg and chatstate is None:
|
||||||
|
@ -2133,12 +2136,18 @@ class Connection:
|
||||||
if msgenc:
|
if msgenc:
|
||||||
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
|
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
|
||||||
|
|
||||||
# chatstates - if peer supports jep85, send chatstates
|
# chatstates - if peer supports jep85 or jep22, send chatstates
|
||||||
# please note that the only valid tag inside a message containing a <body>
|
# please note that the only valid tag inside a message containing a <body>
|
||||||
# tag is the active event
|
# tag is the active event
|
||||||
if chatstate is not None:
|
if chatstate is not None:
|
||||||
msg_iq.setTag(chatstate, {},
|
# JEP-0085
|
||||||
namespace = 'http://jabber.org/protocol/chatstates')
|
msg_iq.setTag(chatstate, namespace = common.xmpp.NS_CHATSTATES)
|
||||||
|
# JEP-0022
|
||||||
|
chatstate_node = msg_iq.setTag('x', namespace = common.xmpp.NS_EVENT)
|
||||||
|
if msg_id:
|
||||||
|
chatstate_node.setTagData('id', msg_id)
|
||||||
|
if chatstate is 'composing' or msgtxt:
|
||||||
|
chatstate_node.addChild(name = 'composing') # we request JEP-0022 composing notification
|
||||||
|
|
||||||
self.connection.send(msg_iq)
|
self.connection.send(msg_iq)
|
||||||
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
||||||
|
|
|
@ -48,6 +48,7 @@ class Contact:
|
||||||
# 'ask' if we sent the first 'active' chatstate and are waiting for reply
|
# 'ask' if we sent the first 'active' chatstate and are waiting for reply
|
||||||
# this holds what WE SEND to contact (our current chatstate)
|
# this holds what WE SEND to contact (our current chatstate)
|
||||||
self.our_chatstate = our_chatstate
|
self.our_chatstate = our_chatstate
|
||||||
|
self.msg_id = None
|
||||||
# this is contact's chatstate
|
# this is contact's chatstate
|
||||||
self.chatstate = chatstate
|
self.chatstate = chatstate
|
||||||
self.last_status_time = last_status_time
|
self.last_status_time = last_status_time
|
||||||
|
|
|
@ -473,6 +473,7 @@ class Interface:
|
||||||
resource = gajim.get_resource_from_jid(array[0])
|
resource = gajim.get_resource_from_jid(array[0])
|
||||||
msg_type = array[4]
|
msg_type = array[4]
|
||||||
chatstate = array[6]
|
chatstate = array[6]
|
||||||
|
msg_id = array[7]
|
||||||
if jid.find('@') <= 0:
|
if jid.find('@') <= 0:
|
||||||
jid = jid.replace('@', '')
|
jid = jid.replace('@', '')
|
||||||
|
|
||||||
|
@ -512,19 +513,21 @@ class Interface:
|
||||||
# Handle chat states
|
# Handle chat states
|
||||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||||
if chat_control and chat_control.type_id == message_control.TYPE_CHAT:
|
if chat_control and chat_control.type_id == message_control.TYPE_CHAT:
|
||||||
if chatstate is not None: # he or she sent us reply, so he supports jep85
|
if chatstate is not None: # he or she sent us reply, so he supports jep85 or jep22
|
||||||
contact.chatstate = chatstate
|
contact.chatstate = chatstate
|
||||||
if contact.our_chatstate == 'ask': # we were jep85 disco?
|
if contact.our_chatstate == 'ask': # we were jep85 disco?
|
||||||
contact.our_chatstate = 'active' # no more
|
contact.our_chatstate = 'active' # no more
|
||||||
|
|
||||||
chat_control.handle_incoming_chatstate()
|
chat_control.handle_incoming_chatstate()
|
||||||
elif contact.chatstate != 'active':
|
elif contact.chatstate != 'active':
|
||||||
# got no valid jep85 answer, peer does not support it
|
# got no valid jep85 no jep22 answer, peer does not support it
|
||||||
contact.chatstate = False
|
contact.chatstate = False
|
||||||
elif contact and chatstate == 'active':
|
elif contact and chatstate == 'active':
|
||||||
# Brand new message, incoming.
|
# Brand new message, incoming.
|
||||||
contact.our_chatstate = chatstate
|
contact.our_chatstate = chatstate
|
||||||
contact.chatstate = chatstate
|
contact.chatstate = chatstate
|
||||||
|
if msg_id: # Do not overwrite an existing msg_id with None
|
||||||
|
contact.msg_id = msg_id
|
||||||
|
|
||||||
if not array[1]: #empty message text
|
if not array[1]: #empty message text
|
||||||
return
|
return
|
||||||
|
|
|
@ -133,12 +133,12 @@ class MessageControl:
|
||||||
n = len(gajim.awaiting_events[self.account][self.contact.jid])
|
n = len(gajim.awaiting_events[self.account][self.contact.jid])
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def send_message(self, message, keyID = '', type = 'chat', chatstate = None):
|
def send_message(self, message, keyID = '', type = 'chat', chatstate = None, msg_id = None):
|
||||||
'''Send the given message to the active tab'''
|
'''Send the given message to the active tab'''
|
||||||
jid = self.contact.jid
|
jid = self.contact.jid
|
||||||
# Send and update history
|
# Send and update history
|
||||||
gajim.connections[self.account].send_message(jid, message, keyID,
|
gajim.connections[self.account].send_message(jid, message, keyID,
|
||||||
type = type, chatstate = chatstate)
|
type = type, chatstate = chatstate, msg_id = msg_id)
|
||||||
|
|
||||||
def position_menu_under_button(self, menu):
|
def position_menu_under_button(self, menu):
|
||||||
#FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786
|
#FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786
|
||||||
|
|
Loading…
Add table
Reference in a new issue