Tue, 15 Apr 2025 19:32:11 -0500
IRCv3: add support for away-notify
This adds support for the away-notify specification and handles AWAY messages
for users and updates their presence accordingly. This also defaults all IRC
contacts to being online.
Testing Done:
Used a temporary `g_warning` to verify the presence changes from another client. Also called in the turtles.
Bugs closed: PIDGIN-18088
Reviewed at https://reviews.imfreedom.org/r/3968/
--- a/protocols/ircv3/purpleircv3connection.c Tue Apr 15 12:51:42 2025 -0500 +++ b/protocols/ircv3/purpleircv3connection.c Tue Apr 15 19:32:11 2025 -0500 @@ -449,6 +449,9 @@ G_CALLBACK(purple_ircv3_message_handler_tagmsg), connection, G_CONNECT_DEFAULT); + g_signal_connect_object(client, "message::" IBIS_MSG_AWAY, + G_CALLBACK(purple_ircv3_message_handler_away), + connection, G_CONNECT_DEFAULT); g_signal_connect_object(client, "message::" IBIS_MSG_JOIN, G_CALLBACK(purple_ircv3_message_handler_join), connection, G_CONNECT_DEFAULT); @@ -583,6 +586,10 @@ */ ibis_capabilities_lookup_and_request(capabilities, IBIS_CAPABILITY_ACCOUNT_TAG); + + /* away-notify tells us when users in a channel go away or come back. */ + ibis_capabilities_lookup_and_request(capabilities, + IBIS_CAPABILITY_AWAY_NOTIFY); } static void @@ -961,6 +968,7 @@ PurpleAccount *account = NULL; PurpleContact *contact = NULL; PurpleContactManager *manager = NULL; + PurplePresence *presence = NULL; IbisTags *tags = NULL; const char *source = NULL; char *nick = NULL; @@ -1001,6 +1009,11 @@ purple_contact_info_set_sid(PURPLE_CONTACT_INFO(contact), source); purple_contact_info_set_display_name(PURPLE_CONTACT_INFO(contact), nick); + /* Grab the presence and set it as online right away. */ + presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact)); + purple_presence_set_primitive(presence, + PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); + g_free(nick); return contact;
--- a/protocols/ircv3/purpleircv3messagehandlers.c Tue Apr 15 12:51:42 2025 -0500 +++ b/protocols/ircv3/purpleircv3messagehandlers.c Tue Apr 15 19:32:11 2025 -0500 @@ -192,6 +192,49 @@ * General Commands *****************************************************************************/ gboolean +purple_ircv3_message_handler_away(G_GNUC_UNUSED IbisClient *client, + G_GNUC_UNUSED const char *command, + IbisMessage *message, + gpointer data) +{ + PurpleIRCv3Connection *connection = data; + PurpleContact *contact = NULL; + PurplePresence *presence = NULL; + GStrv params = NULL; + char *away_message = NULL; + + contact = purple_ircv3_connection_find_or_create_contact(connection, + message); + + presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact)); + + /* Figure out if we have a message. */ + params = ibis_message_get_params(message); + if(params != NULL) { + away_message = g_strjoinv(" ", params); + } + + /* We have a message so we need to set it and possibly set the presence to + * away. + */ + if(!purple_strempty(away_message)) { + purple_presence_set_message(presence, away_message); + + purple_presence_set_primitive(presence, + PURPLE_PRESENCE_PRIMITIVE_AWAY); + } else { + purple_presence_set_message(presence, NULL); + + purple_presence_set_primitive(presence, + PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); + } + + g_clear_pointer(&away_message, g_free); + + return TRUE; +} + +gboolean purple_ircv3_message_handler_join(G_GNUC_UNUSED IbisClient *client, G_GNUC_UNUSED const char *command, IbisMessage *message,
--- a/protocols/ircv3/purpleircv3messagehandlers.h Tue Apr 15 12:51:42 2025 -0500 +++ b/protocols/ircv3/purpleircv3messagehandlers.h Tue Apr 15 19:32:11 2025 -0500 @@ -38,6 +38,7 @@ G_BEGIN_DECLS +G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_away(IbisClient *client, const char *command, IbisMessage *message, gpointer data); G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_join(IbisClient *client, const char *command, IbisMessage *message, gpointer data); G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_part(IbisClient *client, const char *command, IbisMessage *message, gpointer data); G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_namreply(IbisClient *client, const char *command, IbisMessage *message, gpointer data);