aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@src.gnome.org>2008-03-09 04:36:41 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2008-03-09 04:36:41 +0800
commita5c4e3ebc50c91ece5c524f9b381a57dfb330eea (patch)
tree345411998f9a2389b455a395ba63a2e0eac04dfe
parent1ddf5f48b71f425d607126a040af8475d2bef7e9 (diff)
downloadgsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.tar
gsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.tar.gz
gsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.tar.bz2
gsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.tar.lz
gsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.tar.xz
gsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.tar.zst
gsoc2013-empathy-a5c4e3ebc50c91ece5c524f9b381a57dfb330eea.zip
Queue received messages until the sender got his alias.
svn path=/trunk/; revision=713
-rw-r--r--libempathy-gtk/empathy-chat.c8
-rw-r--r--libempathy-gtk/empathy-status-icon.c18
-rw-r--r--libempathy/empathy-message.h2
-rw-r--r--libempathy/empathy-tp-chat.c216
-rw-r--r--libempathy/empathy-tp-contact-factory.c4
5 files changed, 154 insertions, 94 deletions
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index f6e7a2c2a..8af3d573c 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -1504,7 +1504,6 @@ empathy_chat_set_tp_chat (EmpathyChat *chat,
EmpathyTpChat *tp_chat)
{
EmpathyChatPriv *priv;
- GList *messages;
g_return_if_fail (EMPATHY_IS_CHAT (chat));
g_return_if_fail (EMPATHY_IS_TP_CHAT (tp_chat));
@@ -1544,6 +1543,7 @@ empathy_chat_set_tp_chat (EmpathyChat *chat,
priv->tp_chat = g_object_ref (tp_chat);
priv->id = g_strdup (empathy_tp_chat_get_id (tp_chat));
priv->account = g_object_ref (empathy_tp_chat_get_account (tp_chat));
+ empathy_tp_chat_set_acknowledge (tp_chat, TRUE);
if (priv->first_tp_chat) {
chat_add_logs (chat);
@@ -1563,12 +1563,6 @@ empathy_chat_set_tp_chat (EmpathyChat *chat,
G_CALLBACK (chat_destroy_cb),
chat);
- /* Get pending messages, wait until block_events cb before displaying
- * them to have to chance to get alias/avatar of sender. */
- empathy_tp_chat_set_acknowledge (tp_chat, TRUE);
- messages = empathy_tp_chat_get_pendings (tp_chat);
- priv->pending_messages = g_list_concat (priv->pending_messages, messages);
-
if (!priv->sensitive) {
gtk_widget_set_sensitive (chat->input_text_view, TRUE);
empathy_chat_view_append_event (chat->view, _("Connected"));
diff --git a/libempathy-gtk/empathy-status-icon.c b/libempathy-gtk/empathy-status-icon.c
index 78c8b47e0..9f10bd37e 100644
--- a/libempathy-gtk/empathy-status-icon.c
+++ b/libempathy-gtk/empathy-status-icon.c
@@ -322,7 +322,6 @@ status_icon_text_filter_new_channel (EmpathyFilter *filter,
EmpathyStatusIconPriv *priv;
McAccount *account;
EmpathyTpChat *tp_chat;
- GList *messages;
priv = GET_PRIV (icon);
@@ -335,19 +334,9 @@ status_icon_text_filter_new_channel (EmpathyFilter *filter,
g_object_set_data (G_OBJECT (tp_chat), "filter", filter);
g_object_unref (account);
- messages = empathy_tp_chat_get_pendings (tp_chat);
- if (!messages) {
- empathy_debug (DEBUG_DOMAIN, "No pending msg, waiting...");
- g_signal_connect (tp_chat, "message-received",
- G_CALLBACK (status_icon_message_received_cb),
- icon);
- return;
- }
-
- status_icon_message_received_cb (tp_chat, messages->data, icon);
-
- g_list_foreach (messages, (GFunc) g_object_unref, NULL);
- g_list_free (messages);
+ g_signal_connect (tp_chat, "message-received",
+ G_CALLBACK (status_icon_message_received_cb),
+ icon);
}
static void
@@ -783,6 +772,7 @@ status_icon_event_msg_cb (StatusIconEvent *event)
empathy_filter_process (filter,
empathy_tp_chat_get_channel (tp_chat),
TRUE);
+
g_object_unref (tp_chat);
}
diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h
index 668b33311..d1c995fe4 100644
--- a/libempathy/empathy-message.h
+++ b/libempathy/empathy-message.h
@@ -76,7 +76,7 @@ time_t empathy_message_get_timestamp (EmpathyMessage *message);
void empathy_message_set_timestamp (EmpathyMessage *message,
time_t timestamp);
GDate * empathy_message_get_date_and_time (EmpathyMessage *message,
- time_t *timestamp);
+ time_t *timestamp);
EmpathyMessageType empathy_message_type_from_str (const gchar *type_str);
const gchar * empathy_message_type_to_str (EmpathyMessageType type);
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 8e3944298..b96ba48a3 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -28,6 +28,7 @@
#include <libtelepathy/tp-conn.h>
#include <libtelepathy/tp-helpers.h>
#include <libtelepathy/tp-props-iface.h>
+#include <telepathy-glib/util.h>
#include "empathy-tp-chat.h"
#include "empathy-contact-factory.h"
@@ -48,7 +49,8 @@ struct _EmpathyTpChatPriv {
gchar *id;
MissionControl *mc;
gboolean acknowledge;
-
+ gboolean had_pending_messages;
+ GSList *message_queue;
TpChan *tp_chan;
DBusGProxy *props_iface;
DBusGProxy *text_iface;
@@ -159,6 +161,84 @@ tp_chat_build_message (EmpathyTpChat *chat,
}
static void
+tp_chat_sender_ready_notify_cb (EmpathyContact *contact,
+ GParamSpec *param_spec,
+ EmpathyTpChat *chat)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+ EmpathyMessage *message;
+ EmpathyContact *sender;
+ gboolean removed = FALSE;
+ const gchar *name, *id;
+
+ /* Emit all messages queued until we find a message with not
+ * ready sender. When leaving this loop, sender is the first not ready
+ * contact queued and removed tells if at least one message got removed
+ * from the queue. */
+ while (priv->message_queue) {
+ message = priv->message_queue->data;
+ sender = empathy_message_get_sender (message);
+ name = empathy_contact_get_name (sender);
+ id = empathy_contact_get_id (sender);
+
+ if (!tp_strdiff (name, id)) {
+ break;
+ }
+
+ empathy_debug (DEBUG_DOMAIN, "Queued message ready");
+ g_signal_emit (chat, signals[MESSAGE_RECEIVED], 0, message);
+ priv->message_queue = g_slist_remove (priv->message_queue,
+ message);
+ g_object_unref (message);
+ removed = TRUE;
+ }
+
+ if (removed) {
+ g_signal_handlers_disconnect_by_func (contact,
+ tp_chat_sender_ready_notify_cb,
+ chat);
+
+ if (priv->message_queue) {
+ g_signal_connect (sender, "notify::name",
+ G_CALLBACK (tp_chat_sender_ready_notify_cb),
+ chat);
+ }
+ }
+}
+
+static void
+tp_chat_emit_or_queue_message (EmpathyTpChat *chat,
+ EmpathyMessage *message)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+ EmpathyContact *sender;
+ const gchar *name, *id;
+
+ if (priv->message_queue != NULL) {
+ empathy_debug (DEBUG_DOMAIN, "Message queue not empty");
+ priv->message_queue = g_slist_append (priv->message_queue,
+ g_object_ref (message));
+ return;
+ }
+
+ sender = empathy_message_get_sender (message);
+ name = empathy_contact_get_name (sender);
+ id = empathy_contact_get_id (sender);
+ if (tp_strdiff (name, id)) {
+ empathy_debug (DEBUG_DOMAIN, "Message queue empty and sender ready");
+ g_signal_emit (chat, signals[MESSAGE_RECEIVED], 0, message);
+ return;
+ }
+
+ empathy_debug (DEBUG_DOMAIN, "Sender not ready");
+ priv->message_queue = g_slist_append (priv->message_queue,
+ g_object_ref (message));
+ g_signal_connect (sender, "notify::name",
+ G_CALLBACK (tp_chat_sender_ready_notify_cb),
+ chat);
+}
+
+static void
tp_chat_received_cb (DBusGProxy *text_iface,
guint message_id,
guint timestamp,
@@ -173,7 +253,11 @@ tp_chat_received_cb (DBusGProxy *text_iface,
priv = GET_PRIV (chat);
- empathy_debug (DEBUG_DOMAIN, "Message received: %s", message_body);
+ if (!priv->had_pending_messages) {
+ return;
+ }
+
+ empathy_debug (DEBUG_DOMAIN, "Message received: %s", message_body);
message = tp_chat_build_message (chat,
message_type,
@@ -181,7 +265,7 @@ tp_chat_received_cb (DBusGProxy *text_iface,
from_handle,
message_body);
- g_signal_emit (chat, signals[MESSAGE_RECEIVED], 0, message);
+ tp_chat_emit_or_queue_message (EMPATHY_TP_CHAT (chat), message);
g_object_unref (message);
if (priv->acknowledge) {
@@ -212,7 +296,7 @@ tp_chat_sent_cb (DBusGProxy *text_iface,
0,
message_body);
- g_signal_emit (chat, signals[MESSAGE_RECEIVED], 0, message);
+ tp_chat_emit_or_queue_message (EMPATHY_TP_CHAT (chat), message);
g_object_unref (message);
}
@@ -264,6 +348,53 @@ tp_chat_state_changed_cb (DBusGProxy *chat_state_iface,
}
static void
+tp_chat_list_pending_messages_cb (DBusGProxy *proxy,
+ GPtrArray *messages_list,
+ GError *error,
+ gpointer chat)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+ guint i;
+
+ priv->had_pending_messages = TRUE;
+
+ for (i = 0; i < messages_list->len; i++) {
+ EmpathyMessage *message;
+ GValueArray *message_struct;
+ const gchar *message_body;
+ guint message_id;
+ guint timestamp;
+ guint from_handle;
+ guint message_type;
+ guint message_flags;
+
+ message_struct = g_ptr_array_index (messages_list, i);
+
+ message_id = g_value_get_uint (g_value_array_get_nth (message_struct, 0));
+ timestamp = g_value_get_uint (g_value_array_get_nth (message_struct, 1));
+ from_handle = g_value_get_uint (g_value_array_get_nth (message_struct, 2));
+ message_type = g_value_get_uint (g_value_array_get_nth (message_struct, 3));
+ message_flags = g_value_get_uint (g_value_array_get_nth (message_struct, 4));
+ message_body = g_value_get_string (g_value_array_get_nth (message_struct, 5));
+
+ empathy_debug (DEBUG_DOMAIN, "Message pending: %s", message_body);
+
+ message = tp_chat_build_message (chat,
+ message_type,
+ timestamp,
+ from_handle,
+ message_body);
+
+ tp_chat_emit_or_queue_message (chat, message);
+ g_object_unref (message);
+
+ g_value_array_free (message_struct);
+ }
+
+ g_ptr_array_free (messages_list, TRUE);
+}
+
+static void
tp_chat_properties_ready_cb (TpPropsIface *props_iface,
EmpathyTpChat *chat)
{
@@ -382,18 +513,10 @@ tp_chat_finalize (GObject *object)
g_object_unref (priv->tp_chan);
}
- if (priv->factory) {
- g_object_unref (priv->factory);
- }
- if (priv->user) {
- g_object_unref (priv->user);
- }
- if (priv->account) {
- g_object_unref (priv->account);
- }
- if (priv->mc) {
- g_object_unref (priv->mc);
- }
+ g_object_unref (priv->factory);
+ g_object_unref (priv->user);
+ g_object_unref (priv->account);
+ g_object_unref (priv->mc);
g_free (priv->id);
G_OBJECT_CLASS (empathy_tp_chat_parent_class)->finalize (object);
@@ -469,6 +592,10 @@ tp_chat_constructor (GType type,
chat);
}
+ /* FIXME: We do that in a cb to let time to set the acknowledge
+ * property, this property should be required for construct. */
+ g_idle_add ((GSourceFunc) empathy_tp_chat_get_pendings, chat);
+
return chat;
}
@@ -851,64 +978,17 @@ GList *
empathy_tp_chat_get_pendings (EmpathyTpChat *chat)
{
EmpathyTpChatPriv *priv;
- GPtrArray *messages_list;
- guint i;
- GList *messages = NULL;
- GError *error = NULL;
g_return_val_if_fail (EMPATHY_IS_TP_CHAT (chat), NULL);
priv = GET_PRIV (chat);
- /* If we do this call async, don't forget to ignore Received signal
- * until we get the answer */
- if (!tp_chan_type_text_list_pending_messages (priv->text_iface,
- priv->acknowledge,
- &messages_list,
- &error)) {
- empathy_debug (DEBUG_DOMAIN,
- "Error retrieving pending messages: %s",
- error ? error->message : "No error given");
- g_clear_error (&error);
- return NULL;
- }
-
- for (i = 0; i < messages_list->len; i++) {
- EmpathyMessage *message;
- GValueArray *message_struct;
- const gchar *message_body;
- guint message_id;
- guint timestamp;
- guint from_handle;
- guint message_type;
- guint message_flags;
-
- message_struct = g_ptr_array_index (messages_list, i);
-
- message_id = g_value_get_uint (g_value_array_get_nth (message_struct, 0));
- timestamp = g_value_get_uint (g_value_array_get_nth (message_struct, 1));
- from_handle = g_value_get_uint (g_value_array_get_nth (message_struct, 2));
- message_type = g_value_get_uint (g_value_array_get_nth (message_struct, 3));
- message_flags = g_value_get_uint (g_value_array_get_nth (message_struct, 4));
- message_body = g_value_get_string (g_value_array_get_nth (message_struct, 5));
-
- empathy_debug (DEBUG_DOMAIN, "Message pending: %s", message_body);
-
- message = tp_chat_build_message (chat,
- message_type,
- timestamp,
- from_handle,
- message_body);
-
- messages = g_list_prepend (messages, message);
-
- g_value_array_free (message_struct);
- }
- messages = g_list_reverse (messages);
-
- g_ptr_array_free (messages_list, TRUE);
+ tp_chan_type_text_list_pending_messages_async (priv->text_iface,
+ priv->acknowledge,
+ tp_chat_list_pending_messages_cb,
+ chat);
- return messages;
+ return NULL;
}
void
diff --git a/libempathy/empathy-tp-contact-factory.c b/libempathy/empathy-tp-contact-factory.c
index 4621ba394..4e50f6fa8 100644
--- a/libempathy/empathy-tp-contact-factory.c
+++ b/libempathy/empathy-tp-contact-factory.c
@@ -271,10 +271,6 @@ tp_contact_factory_aliases_changed_cb (DBusGProxy *proxy,
continue;
}
- if (G_STR_EMPTY (alias)) {
- alias = NULL;
- }
-
empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (changed cb)",
empathy_contact_get_id (contact),
handle, alias);