summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2010-03-12 23:08:50 +0000
committerJonny Lamb <jonny.lamb@collabora.co.uk>2010-03-12 23:08:50 +0000
commitc7eff0975579f0130d975151b030292d7616204a (patch)
tree53d1631c5d86814f07ff1c09693740a094697a38
parent5c33fcc4b448c047a3b29377c5a9aa2202ffc61a (diff)
parentf28b3d840b79aa9e90430a73f18cf5b6aab06a45 (diff)
Merge branch 'typing-notifications-timeout'
-rw-r--r--butterfly/channel/text.py70
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