summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Kramlich <grim@reaperworld.com>2023-04-18 21:19:39 -0500
committerGary Kramlich <grim@reaperworld.com>2023-04-18 21:19:39 -0500
commit219727b24384de7e80dbe7852f3200298052186f (patch)
treebf5b2ffd59f980b04f885096da879beb507e2ec2
parent03ba57964f9dfd3b0c06d7598a7e78af051a3cb9 (diff)
downloadpidgin-219727b24384de7e80dbe7852f3200298052186f.tar.gz
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/
-rw-r--r--libpurple/protocols/demo/purpledemocontacts.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/libpurple/protocols/demo/purpledemocontacts.c b/libpurple/protocols/demo/purpledemocontacts.c
index 0c64a77050..8e98dc9af8 100644
--- a/libpurple/protocols/demo/purpledemocontacts.c
+++ b/libpurple/protocols/demo/purpledemocontacts.c
@@ -60,6 +60,7 @@ purple_demo_contacts_load_contact_person(JsonObject *person_object,
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 @@ purple_demo_contacts_load_contact_person(JsonObject *person_object,
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 @@ purple_demo_contacts_load_contact_person(JsonObject *person_object,
}
/* 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 @@ purple_demo_contacts_load_contact(PurpleContactManager *manager,
{
PurpleContact *contact = NULL;
PurpleContactInfo *info = NULL;
+ gboolean new_contact = FALSE;
const char *id = NULL;
const char *value = NULL;
@@ -174,8 +197,21 @@ purple_demo_contacts_load_contact(PurpleContactManager *manager,
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(PurpleContactManager *manager,
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);
}
/******************************************************************************