Mon, 14 Aug 2023 23:18:22 -0500
Add an id property to PurpleConversation
And a lookup method it PurpleConversationManager as well.
Testing Done:
Ran the unit tests for conversations and conversation manager doesn't have any.
Reviewed at https://reviews.imfreedom.org/r/2560/
--- a/libpurple/purpleconversation.c Mon Aug 14 22:42:40 2023 -0500 +++ b/libpurple/purpleconversation.c Mon Aug 14 23:18:22 2023 -0500 @@ -31,6 +31,7 @@ #include "server.h" typedef struct { + char *id; PurpleAccount *account; char *name; @@ -45,6 +46,7 @@ enum { PROP_0, + PROP_ID, PROP_ACCOUNT, PROP_NAME, PROP_TITLE, @@ -67,6 +69,22 @@ /************************************************************************** * Helpers **************************************************************************/ +static void +purple_conversation_set_id(PurpleConversation *conversation, const char *id) { + PurpleConversationPrivate *priv = NULL; + + g_return_if_fail(PURPLE_IS_CONVERSATION(conversation)); + + priv = purple_conversation_get_instance_private(conversation); + + if(!purple_strequal(id, priv->id)) { + g_free(priv->id); + priv->id = g_strdup(id); + + g_object_notify_by_pspec(G_OBJECT(conversation), properties[PROP_ID]); + } +} + static gboolean purple_conversation_check_member_equal(gconstpointer a, gconstpointer b) { PurpleConversationMember *member_a = (PurpleConversationMember *)a; @@ -232,6 +250,9 @@ priv = purple_conversation_get_instance_private(conv); switch (param_id) { + case PROP_ID: + purple_conversation_set_id(conv, g_value_get_string(value)); + break; case PROP_ACCOUNT: purple_conversation_set_account(conv, g_value_get_object(value)); break; @@ -259,6 +280,9 @@ PurpleConversation *conv = PURPLE_CONVERSATION(obj); switch(param_id) { + case PROP_ID: + g_value_set_string(value, purple_conversation_get_id(conv)); + break; case PROP_ACCOUNT: g_value_set_object(value, purple_conversation_get_account(conv)); break; @@ -359,6 +383,7 @@ ops->destroy_conversation(conv); } + g_clear_pointer(&priv->id, g_free); g_clear_pointer(&priv->name, g_free); g_clear_pointer(&priv->title, g_free); g_clear_object(&priv->members); @@ -376,6 +401,20 @@ obj_class->get_property = purple_conversation_get_property; obj_class->set_property = purple_conversation_set_property; + /** + * PurpleConversation::id: + * + * An opaque identifier for this conversation. Generally speaking this is + * protocol dependent and should only be used as a unique identifier. + * + * Since: 3.0.0 + */ + properties[PROP_ID] = g_param_spec_string( + "id", "id", + "The identifier for the conversation.", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_ACCOUNT] = g_param_spec_object( "account", "Account", "The account for the conversation.", @@ -541,6 +580,17 @@ return priv->ui_ops; } +const char * +purple_conversation_get_id(PurpleConversation *conversation) { + PurpleConversationPrivate *priv = NULL; + + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), NULL); + + priv = purple_conversation_get_instance_private(conversation); + + return priv->id; +} + void purple_conversation_set_account(PurpleConversation *conv, PurpleAccount *account)
--- a/libpurple/purpleconversation.h Mon Aug 14 22:42:40 2023 -0500 +++ b/libpurple/purpleconversation.h Mon Aug 14 23:18:22 2023 -0500 @@ -151,6 +151,18 @@ PurpleConversationUiOps *purple_conversation_get_ui_ops(PurpleConversation *conv); /** + * purple_conversation_get_id: + * @conversation: The instance. + * + * Gets the opaque identifier from @conversation. + * + * Returns: (nullable): The id of @conversation. + * + * Since: 3.0.0 + */ +const char *purple_conversation_get_id(PurpleConversation *conversation); + +/** * purple_conversation_set_account: * @conv: The conversation. * @account: The purple_account.
--- a/libpurple/purpleconversationmanager.c Mon Aug 14 22:42:40 2023 -0500 +++ b/libpurple/purpleconversationmanager.c Mon Aug 14 23:18:22 2023 -0500 @@ -76,6 +76,20 @@ return (purple_chat_conversation_get_id(chat) == id); } +static gboolean +purple_conversation_has_id(PurpleConversation *conversation, gpointer data) { + const char *needle = data; + const char *haystack = NULL; + + if(!PURPLE_IS_CONVERSATION(conversation)) { + return FALSE; + } + + haystack = purple_conversation_get_id(conversation); + + return purple_strequal(needle, haystack); +} + static PurpleConversation * purple_conversation_manager_find_internal(PurpleConversationManager *manager, PurpleAccount *account, @@ -330,3 +344,16 @@ purple_conversation_chat_has_id, GINT_TO_POINTER(id)); } + +PurpleConversation * +purple_conversation_manager_find_with_id(PurpleConversationManager *manager, + PurpleAccount *account, + const char *id) +{ + g_return_val_if_fail(PURPLE_IS_CONVERSATION_MANAGER(manager), NULL); + g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); + + return purple_conversation_manager_find_internal(manager, account, NULL, + purple_conversation_has_id, + (gpointer)id); +}
--- a/libpurple/purpleconversationmanager.h Mon Aug 14 22:42:40 2023 -0500 +++ b/libpurple/purpleconversationmanager.h Mon Aug 14 23:18:22 2023 -0500 @@ -195,6 +195,21 @@ */ PurpleConversation *purple_conversation_manager_find_chat_by_id(PurpleConversationManager *manager, PurpleAccount *account, gint id); +/** + * purple_conversation_manager_find_with_id: + * @manager: The instance. + * @account: The account the conversation belongs to. + * @id: The identifier of the conversation. + * + * Looks for a registered conversation belonging to @account with an id of @id. + * + * Returns: (transfer none) (nullable): The [class@PurpleConversation] if + * found, otherwise %NULL. + * + * Since: 3.0.0 + */ +PurpleConversation *purple_conversation_manager_find_with_id(PurpleConversationManager *manager, PurpleAccount *account, const char *id); + G_END_DECLS #endif /* PURPLE_CONVERSATION_MANAGER_H */
--- a/libpurple/tests/test_conversation.c Mon Aug 14 22:42:40 2023 -0500 +++ b/libpurple/tests/test_conversation.c Mon Aug 14 23:18:22 2023 -0500 @@ -33,8 +33,9 @@ PurpleConversation *conversation = NULL; PurpleConversationManager *conversation_manager = NULL; GListModel *members = NULL; - gchar *name = NULL; - gchar *title = NULL; + char *id = NULL; + char *name = NULL; + char *title = NULL; account = purple_account_new("test", "test"); @@ -44,6 +45,7 @@ */ conversation = g_object_new( PURPLE_TYPE_CONVERSATION, + "id", "id1", "account", account, "features", PURPLE_CONNECTION_FLAG_HTML, "name", "name1", @@ -52,6 +54,7 @@ /* Now use g_object_get to read all of the properties. */ g_object_get(conversation, + "id", &id, "account", &account1, "features", &features, "members", &members, @@ -60,6 +63,7 @@ NULL); /* Compare all the things. */ + g_assert_cmpstr(id, ==, "id1"); g_assert_true(account1 == account); g_assert_cmpint(features, ==, PURPLE_CONNECTION_FLAG_HTML); g_assert_true(G_IS_LIST_MODEL(members)); @@ -79,10 +83,11 @@ purple_conversation_manager_unregister(conversation_manager, conversation); /* Free/unref all the things. */ + g_clear_pointer(&id, g_free); g_clear_object(&account1); g_clear_object(&members); - g_free(name); - g_free(title); + g_clear_pointer(&name, g_free); + g_clear_pointer(&title, g_free); g_clear_object(&account); g_clear_object(&conversation);