summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2018-03-22 22:30:40 +0000
committerDavid Woodhouse <dwmw2@infradead.org>2018-03-22 22:30:40 +0000
commitb55bcb9fd4afc6ee4c5485532d07fd327675dc17 (patch)
treece399db564fa604992f0e489062c4f566e697fec
parent39e1cef2f892d8d1c791c716b4fd2f07f6573257 (diff)
downloadpidgin-b55bcb9fd4afc6ee4c5485532d07fd327675dc17.tar.gz
Create transient IM buddies for accounts which can cope
We need a PurpleBuddy in order for full names (aliases), presence status and photos to be displayed for IM peers that aren't otherwise in the buddy list. Doing it in libpurple is a whole lot saner than having the PRPL hook into "conversation-created" and "deleting-conversation" signals and trying to create them for itself.
-rw-r--r--libpurple/conversation.c53
-rw-r--r--libpurple/prpl.h9
2 files changed, 61 insertions, 1 deletions
diff --git a/libpurple/conversation.c b/libpurple/conversation.c
index 72938044c5..26c60f690f 100644
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -327,6 +327,55 @@ purple_conversation_chat_cleanup_for_rejoin(PurpleConversation *conv)
purple_conversation_update(conv, PURPLE_CONV_UPDATE_CHATLEFT);
}
+/* Meaningful name in case a UI doesn't actually honour the INVISIBLE flag */
+#define TRANSIENT_GROUP_NAME _("(internal) Temporary IM peers")
+
+static void
+purple_conversation_ensure_buddy(PurpleAccount *account, PurpleConnection *gc,
+ const char *name)
+{
+ PurplePluginProtocolInfo *prpl_info;
+ PurpleBuddy *buddy;
+ PurpleGroup *group;
+
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
+
+ if ((prpl_info->options & OPT_PROTO_TRANSIENT_BUDDIES) &&
+ !purple_find_buddy(account, name)) {
+ group = purple_find_group(TRANSIENT_GROUP_NAME);
+ if (!group) {
+ group = purple_group_new(TRANSIENT_GROUP_NAME);
+ purple_blist_node_set_flags(PURPLE_BLIST_NODE(group),
+ PURPLE_BLIST_NODE_FLAG_NO_SAVE | PURPLE_BLIST_NODE_FLAG_INVISIBLE);
+ purple_blist_add_group(group, NULL);
+ }
+ buddy = purple_buddy_new(account, name, NULL);
+ purple_blist_node_set_flags(PURPLE_BLIST_NODE(buddy),
+ PURPLE_BLIST_NODE_FLAG_NO_SAVE | PURPLE_BLIST_NODE_FLAG_INVISIBLE);
+
+ purple_blist_add_buddy(buddy, NULL, group, NULL);
+ purple_account_add_buddy(account, buddy);
+ }
+}
+
+static void
+purple_conversation_release_buddy(PurpleAccount *account, const char *name)
+{
+ PurpleBuddy *buddy;
+ PurpleGroup *group;
+
+ group = purple_find_group(TRANSIENT_GROUP_NAME);
+ if (!group)
+ return;
+
+ buddy = purple_find_buddy_in_group(account, name, group);
+ if (!buddy)
+ return;
+
+ purple_account_remove_buddy(account, buddy, group);
+ purple_blist_remove_buddy(buddy);
+}
+
PurpleConversation *
purple_conversation_new(PurpleConversationType type, PurpleAccount *account,
const char *name)
@@ -403,6 +452,8 @@ purple_conversation_new(PurpleConversationType type, PurpleAccount *account,
purple_conversation_set_logging(conv, TRUE);
open_log(conv);
}
+
+ purple_conversation_ensure_buddy(account, gc, name);
}
else if (type == PURPLE_CONV_TYPE_CHAT)
{
@@ -484,6 +535,8 @@ purple_conversation_destroy(PurpleConversation *conv)
if (gc && prpl_info->convo_closed != NULL)
prpl_info->convo_closed(gc, name);
+
+ purple_conversation_release_buddy(conv->account, conv->name);
}
else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
{
diff --git a/libpurple/prpl.h b/libpurple/prpl.h
index b1b20d0c5b..c7af634173 100644
--- a/libpurple/prpl.h
+++ b/libpurple/prpl.h
@@ -209,7 +209,14 @@ typedef enum
* along with an invitation.
* @since 2.8.0
*/
- OPT_PROTO_INVITE_MESSAGE = 0x00000800
+ OPT_PROTO_INVITE_MESSAGE = 0x00000800,
+
+ /**
+ * Indicates that this protocol supports creating invisible buddies for
+ * reporting presence/alias of IM peers.
+ * @since 2.14.0
+ */
+ OPT_PROTO_TRANSIENT_BUDDIES = 0x00001000,
} PurpleProtocolOptions;