pidgin/pidgin

d3fb75a80601
Parents 56b8487d9020
Children cfa7c940ed62
Don't duplicate contacts in the demo protocol when reconnecting

Previously, we were always creating new contacts and persons on connection. This
ends up with duplicates when we run the connection error actions which is
obviously not what we want.

Testing Done:
Ran the connection error actions and verified that we did not get duplicate contacts and persons.

Reviewed at https://reviews.imfreedom.org/r/2436/
--- a/libpurple/protocols/demo/purpledemocontacts.c Thu Apr 13 15:55:28 2023 -0500
+++ b/libpurple/protocols/demo/purpledemocontacts.c Tue Apr 18 21:19:39 2023 -0500
@@ -60,6 +60,7 @@
PurpleContactInfo *info)
{
PurplePerson *person = NULL;
+ gboolean new_person = FALSE;
const char *value = NULL;
/* If the person has an id, grab it so we can use it when constructing the
@@ -69,8 +70,27 @@
value = json_object_get_string_member(person_object, "id");
}
- /* Now create the person with the optional id. */
- person = g_object_new(PURPLE_TYPE_PERSON, "id", value, NULL);
+ /* See if the contact has an existing person. */
+ person = purple_contact_info_get_person(info);
+ if(PURPLE_IS_PERSON(person)) {
+ const char *existing_id = NULL;
+
+ /* If the existing person's id doesn't match the new one, NULL out
+ * person so it'll be recreated with the new id.
+ */
+ existing_id = purple_person_get_id(person);
+ if(!purple_strequal(existing_id, value)) {
+ person = NULL;
+ }
+ }
+
+ /* If the person didn't exist or it had a different id, create a new person
+ * with the id.
+ */
+ if(!PURPLE_IS_PERSON(person)) {
+ person = g_object_new(PURPLE_TYPE_PERSON, "id", value, NULL);
+ new_person = TRUE;
+ }
/* Alias */
if(json_object_has_member(person_object, "alias")) {
@@ -81,10 +101,12 @@
}
/* Create the link between the person and the contact info. */
- purple_person_add_contact_info(person, info);
- purple_contact_info_set_person(info, person);
+ if(new_person) {
+ purple_person_add_contact_info(person, info);
+ purple_contact_info_set_person(info, person);
- g_clear_object(&person);
+ g_clear_object(&person);
+ }
}
static void
@@ -166,6 +188,7 @@
{
PurpleContact *contact = NULL;
PurpleContactInfo *info = NULL;
+ gboolean new_contact = FALSE;
const char *id = NULL;
const char *value = NULL;
@@ -174,8 +197,21 @@
id = json_object_get_string_member(contact_object, "id");
}
- /* Create the contact using the id if one was provided. */
- contact = purple_contact_new(account, id);
+ /* Look for an existing contact before creating a new one. This stops us
+ * from getting multiples when we trigger connection errors.
+ */
+ if(!purple_strempty(id)) {
+ contact = purple_contact_manager_find_with_id(manager, account, id);
+ }
+
+ /* If we didn't find an existing contact, create it now with the provided
+ * id.
+ */
+ if(!PURPLE_IS_CONTACT(contact)) {
+ contact = purple_contact_new(account, id);
+ new_contact = TRUE;
+ }
+
info = PURPLE_CONTACT_INFO(contact);
/* Alias */
@@ -232,8 +268,12 @@
purple_demo_contacts_load_contact_presence(presence_object, info);
}
- /* Finally add the contact to the contact manager. */
- purple_contact_manager_add(manager, contact);
+ /* Finally add the contact to the contact manager if it's new. */
+ if(new_contact) {
+ purple_contact_manager_add(manager, contact);
+ }
+
+ g_clear_object(&contact);
}
/******************************************************************************