]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-contact.c
Merge branch 'folks-async-and-prepare'
[empathy.git] / libempathy / empathy-contact.c
index 57a4449c396a39286295192d42cdb2bf70f2e424..6842cde09d8078f60afd055236836eabf5d551bb 100644 (file)
@@ -54,7 +54,6 @@ typedef struct {
   gchar *alias;
   EmpathyAvatar *avatar;
   TpConnectionPresenceType presence;
-  gchar *presence_message;
   guint handle;
   EmpathyCapabilities capabilities;
   gboolean is_user;
@@ -67,6 +66,7 @@ typedef struct {
    * more fields by searching the address using geoclue.
    */
   GHashTable *location;
+  GHashTable *groups;
 } EmpathyContactPriv;
 
 static void contact_finalize (GObject *object);
@@ -135,8 +135,6 @@ tp_contact_notify_cb (TpContact *tp_contact,
     priv->presence = presence;
     g_object_notify (contact, "presence");
   }
-  else if (!tp_strdiff (param->name, "presence-message"))
-    g_object_notify (contact, "presence-message");
   else if (!tp_strdiff (param->name, "identifier"))
     g_object_notify (contact, "id");
   else if (!tp_strdiff (param->name, "handle"))
@@ -160,6 +158,15 @@ tp_contact_notify_cb (TpContact *tp_contact,
     }
 }
 
+static void
+folks_persona_notify_cb (FolksPersona *folks_persona,
+                         GParamSpec *param,
+                         GObject *contact)
+{
+  if (!tp_strdiff (param->name, "presence-message"))
+    g_object_notify (contact, "presence-message");
+}
+
 static void
 contact_dispose (GObject *object)
 {
@@ -179,7 +186,11 @@ contact_dispose (GObject *object)
   priv->account = NULL;
 
   if (priv->persona)
-    g_object_unref (priv->persona);
+    {
+      g_signal_handlers_disconnect_by_func (priv->persona,
+          folks_persona_notify_cb, object);
+      g_object_unref (priv->persona);
+    }
   priv->persona = NULL;
 
   if (priv->avatar != NULL)
@@ -334,6 +345,7 @@ empathy_contact_init (EmpathyContact *contact)
   contact->priv = priv;
 
   priv->location = NULL;
+  priv->groups = NULL;
 }
 
 static void
@@ -345,9 +357,10 @@ contact_finalize (GObject *object)
 
   DEBUG ("finalize: %p", object);
 
+  if (priv->groups != NULL)
+    g_hash_table_destroy (priv->groups);
   g_free (priv->alias);
   g_free (priv->id);
-  g_free (priv->presence_message);
 
   G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
 }
@@ -629,6 +642,16 @@ empathy_contact_set_alias (EmpathyContact *contact,
 
   g_object_ref (contact);
 
+  /* Set the alias on the persona if possible */
+  persona = empathy_contact_get_persona (contact);
+  if (persona != NULL && FOLKS_IS_ALIAS (persona))
+    {
+      DEBUG ("Setting alias for contact %s to %s",
+          empathy_contact_get_id (contact), alias);
+
+      folks_alias_set_alias (FOLKS_ALIAS (persona), alias);
+    }
+
   if (tp_strdiff (alias, priv->alias))
     {
       g_free (priv->alias);
@@ -639,6 +662,56 @@ empathy_contact_set_alias (EmpathyContact *contact,
   g_object_unref (contact);
 }
 
+static void
+groups_change_group_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  FolksGroups *groups = FOLKS_GROUPS (source);
+  GError *error = NULL;
+
+  folks_groups_change_group_finish (groups, result, &error);
+  if (error != NULL)
+    {
+      g_warning ("failed to change group: %s", error->message);
+      g_clear_error (&error);
+    }
+}
+
+void
+empathy_contact_change_group (EmpathyContact *contact, const gchar *group,
+    gboolean is_member)
+{
+  EmpathyContactPriv *priv;
+  FolksPersona *persona;
+
+  g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+  g_return_if_fail (group != NULL);
+
+  priv = GET_PRIV (contact);
+
+  /* Normally pass through the changes to the persona */
+  persona = empathy_contact_get_persona (contact);
+  if (persona != NULL)
+    {
+      if (FOLKS_IS_GROUPS (persona))
+        folks_groups_change_group (FOLKS_GROUPS (persona), group, is_member,
+          groups_change_group_cb, contact);
+      return;
+    }
+
+  /* If the persona doesn't exist yet, we have to cache the changes until it
+   * does */
+  if (priv->groups == NULL)
+    {
+      priv->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+          NULL);
+    }
+
+  g_hash_table_insert (priv->groups, g_strdup (group),
+      GUINT_TO_POINTER (is_member));
+}
+
 EmpathyAvatar *
 empathy_contact_get_avatar (EmpathyContact *contact)
 {
@@ -756,7 +829,7 @@ empathy_contact_set_persona (EmpathyContact *contact,
   EmpathyContactPriv *priv;
 
   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-  g_return_if_fail (FOLKS_IS_PERSONA (persona));
+  g_return_if_fail (TPF_IS_PERSONA (persona));
 
   priv = GET_PRIV (contact);
 
@@ -767,7 +840,23 @@ empathy_contact_set_persona (EmpathyContact *contact,
     g_object_unref (priv->persona);
   priv->persona = g_object_ref (persona);
 
+  g_signal_connect (priv->persona, "notify",
+    G_CALLBACK (folks_persona_notify_cb), contact);
+
   g_object_notify (G_OBJECT (contact), "persona");
+
+  /* Set the persona's alias, since ours could've been set using
+   * empathy_contact_set_alias() before we had a persona; this happens when
+   * adding a contact. */
+  empathy_contact_set_alias (contact, priv->alias);
+
+  /* Set the persona's groups */
+  if (priv->groups != NULL)
+    {
+      folks_groups_set_groups (FOLKS_GROUPS (persona), priv->groups);
+      g_hash_table_destroy (priv->groups);
+      priv->groups = NULL;
+    }
 }
 
 TpConnection *
@@ -832,10 +921,10 @@ empathy_contact_get_presence_message (EmpathyContact *contact)
 
   priv = GET_PRIV (contact);
 
-  if (priv->tp_contact != NULL)
-    return tp_contact_get_presence_message (priv->tp_contact);
+  if (priv->persona != NULL)
+    return folks_presence_get_presence_message (FOLKS_PRESENCE (priv->persona));
 
-  return priv->presence_message;
+  return NULL;
 }
 
 void
@@ -846,13 +935,11 @@ empathy_contact_set_presence_message (EmpathyContact *contact,
 
   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
-  if (!tp_strdiff (message, priv->presence_message))
-    return;
-
-  g_free (priv->presence_message);
-  priv->presence_message = g_strdup (message);
-
-  g_object_notify (G_OBJECT (contact), "presence-message");
+  if (priv->persona != NULL)
+    {
+      folks_presence_set_presence_message (FOLKS_PRESENCE (priv->persona),
+          message);
+    }
 }
 
 guint