diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2010-03-12 23:08:50 +0000 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2010-03-12 23:08:50 +0000 |
commit | c7eff0975579f0130d975151b030292d7616204a (patch) | |
tree | 53d1631c5d86814f07ff1c09693740a094697a38 | |
parent | 5c33fcc4b448c047a3b29377c5a9aa2202ffc61a (diff) | |
parent | f28b3d840b79aa9e90430a73f18cf5b6aab06a45 (diff) |
Merge branch 'typing-notifications-timeout'
-rw-r--r-- | butterfly/channel/text.py | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/butterfly/channel/text.py b/butterfly/channel/text.py index e0c5728..eb19f32 100644 --- a/butterfly/channel/text.py +++ b/butterfly/channel/text.py @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import gobject import logging import weakref import time @@ -41,6 +42,8 @@ class ButterflyTextChannel( def __init__(self, conn, manager, conversation, props, object_path=None): self._recv_id = 0 self._conn_ref = weakref.ref(conn) + self._send_typing_notification_timeout = 0 + self._typing_notifications = dict() self._conversation = None @@ -49,6 +52,23 @@ class ButterflyTextChannel( telepathy.server.ChannelInterfaceChatState.__init__(self) papyon.event.ConversationEventInterface.__init__(self, conn.msn_client) + def __del__(self): + self._remove_typing_timeouts() + + def _remove_typing_timeouts(self): + # Remove any timeouts we had running. + handle = ButterflyHandleFactory(self._conn_ref(), 'self') + + if self._send_typing_notification_timeout != 0: + gobject.source_remove(self._send_typing_notification_timeout) + self._send_typing_notification_timeout = 0 + self.ChatStateChanged(handle, telepathy.CHANNEL_CHAT_STATE_ACTIVE) + + for handle, tag in self._typing_notifications.items(): + gobject.source_remove(tag) + self.ChatStateChanged(handle, telepathy.CHANNEL_CHAT_STATE_ACTIVE) + self._typing_notifications = dict() + def steal_conversation(self): if self._conversation is None: return None @@ -56,6 +76,8 @@ class ButterflyTextChannel( ret = self._conversation self._conversation = None + self._remove_typing_timeouts() + # We don't want this object to receive events regarding the conversation # that has been stolen. It would be nice if papyon had an API to do this, # as opposed to having to access the _events_handlers weak set of the @@ -71,11 +93,39 @@ class ButterflyTextChannel( else: return set() + def _send_typing_notification(self): + # No need to emit ChatStateChanged in this method becuase it will not + # have changed from composing otherwise this source will have been + # removed. + + if self._conversation is not None: + # Send this notification and keep sending them. + self._conversation.send_typing_notification() + return True + else: + # Don't bother sending anymore as we have no conversation. + self._send_typing_notification_timeout = 0 + return False + def SetChatState(self, state): # Not useful if we dont have a conversation. if self._conversation is not None: if state == telepathy.CHANNEL_CHAT_STATE_COMPOSING: + # User has started typing. self._conversation.send_typing_notification() + + # If we haven't already set a timeout, add one for every 5s. + if self._send_typing_notification_timeout == 0: + self._send_typing_notification_timeout = \ + gobject.timeout_add_seconds(5, self._send_typing_notification) + + else: + # User is gone/inactive/active/paused, which basically means "not typing". + # If we have a timeout for sending typing notifications, remove it. + if self._send_typing_notification_timeout != 0: + gobject.source_remove(self._send_typing_notification_timeout) + self._send_typing_notification_timeout = 0 + handle = ButterflyHandleFactory(self._conn_ref(), 'self') self.ChatStateChanged(handle, state) @@ -96,6 +146,7 @@ class ButterflyTextChannel( def Close(self): if self._conversation is not None: self._conversation.leave() + self._remove_typing_timeouts() telepathy.server.ChannelTypeText.Close(self) self.remove_from_connection() @@ -104,11 +155,30 @@ class ButterflyTextChannel( def GetSelfHandle(self): return self._conn_ref().GetSelfHandle() + def _contact_typing_notification_timeout(self, handle): + # Contact hasn't sent a typing notification for ten seconds. He or she + # has probably stopped typing. + del self._typing_notifications[handle] + self.ChatStateChanged(handle, telepathy.CHANNEL_CHAT_STATE_ACTIVE) + return False + # papyon.event.ConversationEventInterface def on_conversation_user_typing(self, contact): handle = ButterflyHandleFactory(self._conn_ref(), 'contact', contact.account, contact.network_id) logger.info("User %s is typing" % unicode(handle)) + + # Remove any previous timeout. + if handle in self._typing_notifications: + gobject.source_remove(self._typing_notifications[handle]) + del self._typing_notifications[handle] + + # Add a new timeout of 10 seconds. If we don't receive another typing + # notification in that time, the contact has probably stopped typing, + # so we should set the chat state back to active for that handle. + self._typing_notifications[handle] = \ + gobject.timeout_add_seconds(10, self._contact_typing_notification_timeout, handle) + self.ChatStateChanged(handle, telepathy.CHANNEL_CHAT_STATE_COMPOSING) # papyon.event.ConversationEventInterface |