pidgin/pidgin

5ad29b5bf1c7
Parents 4577958c4c6a
Children 225762d4e206
Create PurpleAuthorizationRequestNotification

This is the first discrete notifications objects after /r/3009. This also fixes
an issue in /r/3009 where PurpleNotification was still marked as a final type.

Testing Done:
I have a WIP branch for updating the Pidgin side that I used to verify functionality but it has some issues so isn't included here.

Also ran the unit tests under valgrind.

Reviewed at https://reviews.imfreedom.org/r/3035/
--- a/libpurple/meson.build Thu Mar 21 22:18:04 2024 -0500
+++ b/libpurple/meson.build Thu Mar 21 22:20:50 2024 -0500
@@ -39,6 +39,7 @@
'purpleaddcontactrequest.c',
'purpleattachment.c',
'purpleauthorizationrequest.c',
+ 'purpleauthorizationrequestnotification.c',
'purpleavatar.c',
'purplebuddypresence.c',
'purplechanneljoindetails.c',
@@ -164,6 +165,7 @@
'purpleaccountusersplit.h',
'purpleaddcontactrequest.h',
'purpleauthorizationrequest.h',
+ 'purpleauthorizationrequestnotification.h',
'purpleavatar.h',
'purplebuddypresence.h',
'purplechanneljoindetails.h',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleauthorizationrequestnotification.c Thu Mar 21 22:20:50 2024 -0500
@@ -0,0 +1,228 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n-lib.h>
+
+#include "purpleauthorizationrequestnotification.h"
+
+enum {
+ PROP_0,
+ PROP_AUTHORIZATION_REQUEST,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL, 0};
+
+struct _PurpleAuthorizationRequestNotification {
+ PurpleNotification parent;
+
+ PurpleAuthorizationRequest *authorization_request;
+};
+
+static void
+purple_authorization_request_notification_request_changed_cb(GObject *obj,
+ GParamSpec *pspec,
+ gpointer data);
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_authorization_request_notification_update(PurpleAuthorizationRequestNotification *auth_notification)
+{
+ PurpleAccount *account = NULL;
+ PurpleAuthorizationRequest *request = NULL;
+ PurpleContactInfo *info = NULL;
+ PurpleNotification *notification = PURPLE_NOTIFICATION(auth_notification);
+ char *title = NULL;
+ const char *alias = NULL;
+ const char *username = NULL;
+
+ request = auth_notification->authorization_request;
+ account = purple_authorization_request_get_account(request);
+ info = PURPLE_CONTACT_INFO(account);
+ username = purple_authorization_request_get_username(request);
+ alias = purple_authorization_request_get_alias(request);
+
+ if(!purple_strempty(alias)) {
+ title = g_strdup_printf(_("%s (%s) would like to add %s to their"
+ " contact list"),
+ alias, username,
+ purple_contact_info_get_username(info));
+ } else {
+ title = g_strdup_printf(_("%s would like to add %s to their contact"
+ " list"),
+ username,
+ purple_contact_info_get_username(info));
+ }
+
+ purple_notification_set_title(notification, title);
+ g_free(title);
+}
+
+static void
+purple_authorization_request_notification_set_request(PurpleAuthorizationRequestNotification *notification,
+ PurpleAuthorizationRequest *request)
+{
+ g_return_if_fail(PURPLE_IS_AUTHORIZATION_REQUEST_NOTIFICATION(notification));
+
+ if(g_set_object(&notification->authorization_request, request)) {
+ if(PURPLE_IS_AUTHORIZATION_REQUEST(request)) {
+ g_signal_connect_object(request, "notify",
+ G_CALLBACK(purple_authorization_request_notification_request_changed_cb),
+ notification, 0);
+
+ purple_authorization_request_notification_update(notification);
+ }
+
+ g_object_notify_by_pspec(G_OBJECT(notification),
+ properties[PROP_AUTHORIZATION_REQUEST]);
+ }
+}
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+purple_authorization_request_notification_request_changed_cb(G_GNUC_UNUSED GObject *obj,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ gpointer data)
+{
+ purple_authorization_request_notification_update(data);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_FINAL_TYPE(PurpleAuthorizationRequestNotification,
+ purple_authorization_request_notification,
+ PURPLE_TYPE_NOTIFICATION)
+
+static void
+purple_authorization_request_notification_finalize(GObject *object) {
+ PurpleAuthorizationRequestNotification *notification = NULL;
+
+ notification = PURPLE_AUTHORIZATION_REQUEST_NOTIFICATION(object);
+
+ g_clear_object(&notification->authorization_request);
+
+ G_OBJECT_CLASS(purple_authorization_request_notification_parent_class)->finalize(object);
+}
+
+static void
+purple_authorization_request_notification_get_property(GObject *obj,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleAuthorizationRequestNotification *notification = NULL;
+
+ notification = PURPLE_AUTHORIZATION_REQUEST_NOTIFICATION(obj);
+
+ switch(param_id) {
+ case PROP_AUTHORIZATION_REQUEST:
+ g_value_set_object(value,
+ purple_authorization_request_notification_get_request(notification));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_authorization_request_notification_set_property(GObject *obj,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleAuthorizationRequestNotification *notification = NULL;
+
+ notification = PURPLE_AUTHORIZATION_REQUEST_NOTIFICATION(obj);
+
+ switch(param_id) {
+ case PROP_AUTHORIZATION_REQUEST:
+ purple_authorization_request_notification_set_request(notification,
+ g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_authorization_request_notification_init(G_GNUC_UNUSED PurpleAuthorizationRequestNotification *notification)
+{
+}
+
+static void
+purple_authorization_request_notification_class_init(PurpleAuthorizationRequestNotificationClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->finalize = purple_authorization_request_notification_finalize;
+ obj_class->get_property = purple_authorization_request_notification_get_property;
+ obj_class->set_property = purple_authorization_request_notification_set_property;
+
+ /**
+ * PurpleAuthorizationRequestNotification:authorization-request:
+ *
+ * The [class@AuthorizationRequest] that this notification was created for.
+ *
+ * Since: 3.0
+ */
+ properties[PROP_AUTHORIZATION_REQUEST] = g_param_spec_object(
+ "authorization-request", "authorization-request",
+ "The authorization request this notification is for.",
+ PURPLE_TYPE_AUTHORIZATION_REQUEST,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleNotification *
+purple_authorization_request_notification_new(PurpleAuthorizationRequest *request)
+{
+ PurpleAccount *account = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_AUTHORIZATION_REQUEST(request), NULL);
+
+ account = purple_authorization_request_get_account(request);
+
+ return g_object_new(
+ PURPLE_TYPE_AUTHORIZATION_REQUEST_NOTIFICATION,
+ "account", account,
+ "authorization-request", request,
+ NULL);
+}
+
+PurpleAuthorizationRequest *
+purple_authorization_request_notification_get_request(PurpleAuthorizationRequestNotification *notification)
+{
+ g_return_val_if_fail(PURPLE_IS_AUTHORIZATION_REQUEST_NOTIFICATION(notification),
+ NULL);
+
+ return notification->authorization_request;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleauthorizationrequestnotification.h Thu Mar 21 22:20:50 2024 -0500
@@ -0,0 +1,83 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_AUTHORIZATION_REQUEST_NOTIFICATION_H
+#define PURPLE_AUTHORIZATION_REQUEST_NOTIFICATION_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "purpleauthorizationrequest.h"
+#include "purplenotification.h"
+#include "purpleversion.h"
+
+G_BEGIN_DECLS
+
+/**
+ * PurpleAuthorizationRequestNotification:
+ *
+ * A [class@Notification] for [class@AuthorizationRequest]s.
+ *
+ * Since: 3.0
+ */
+
+#define PURPLE_TYPE_AUTHORIZATION_REQUEST_NOTIFICATION (purple_authorization_request_notification_get_type())
+
+PURPLE_AVAILABLE_IN_3_0
+G_DECLARE_FINAL_TYPE(PurpleAuthorizationRequestNotification,
+ purple_authorization_request_notification,
+ PURPLE, AUTHORIZATION_REQUEST_NOTIFICATION,
+ PurpleNotification)
+
+/**
+ * purple_authorization_request_notification_new:
+ * @request: The authorization request instance.
+ *
+ * Creates a new [class@Notification] for @request.
+ *
+ * Returns: The new notification.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+PurpleNotification *purple_authorization_request_notification_new(PurpleAuthorizationRequest *request);
+
+/**
+ * purple_authorization_request_notification_get_request:
+ * @notification: The instance.
+ *
+ * Gets the [class@AuthorizationRequest] for @notification.
+ *
+ * Returns: (transfer none): The authorization request.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+PurpleAuthorizationRequest *purple_authorization_request_notification_get_request(PurpleAuthorizationRequestNotification *notification);
+
+G_END_DECLS
+
+#endif /* PURPLE_AUTHORIZATION_REQUEST_NOTIFICATION_H */
--- a/libpurple/tests/meson.build Thu Mar 21 22:18:04 2024 -0500
+++ b/libpurple/tests/meson.build Thu Mar 21 22:20:50 2024 -0500
@@ -2,6 +2,7 @@
'account_option',
'account_manager',
'authorization_request',
+ 'authorization_request_notification',
'channel_join_details',
'circular_buffer',
'create_conversation_details',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_authorization_request_notification.c Thu Mar 21 22:20:50 2024 -0500
@@ -0,0 +1,142 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+
+#include <purple.h>
+
+#include "test_ui.h"
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+test_purple_authorization_request_notification_notify_cb(GObject *obj,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ gpointer data)
+{
+ guint *counter = data;
+
+ g_assert_true(PURPLE_IS_NOTIFICATION(obj));
+
+ *counter = *counter + 1;
+}
+
+/******************************************************************************
+ * Tests
+ *****************************************************************************/
+static void
+test_purple_authorization_request_notification_new(void) {
+ PurpleAccount *account = NULL;
+ PurpleAuthorizationRequest *request = NULL;
+ PurpleNotification *notification = NULL;
+
+ account = purple_account_new("test", "test");
+ request = purple_authorization_request_new(account, "remote-username");
+ notification = purple_authorization_request_notification_new(request);
+
+ g_assert_true(PURPLE_IS_NOTIFICATION(notification));
+ g_assert_true(PURPLE_IS_AUTHORIZATION_REQUEST_NOTIFICATION(notification));
+
+ g_assert_finalize_object(notification);
+
+ g_clear_object(&request);
+ g_clear_object(&account);
+}
+
+static void
+test_purple_authorization_request_notification_properties(void) {
+ PurpleAccount *account = NULL;
+ PurpleAuthorizationRequest *request = NULL;
+ PurpleAuthorizationRequest *request1 = NULL;
+ PurpleNotification *notification = NULL;
+
+ account = purple_account_new("test", "test");
+ request = purple_authorization_request_new(account, "username");
+
+ notification = g_object_new(
+ PURPLE_TYPE_AUTHORIZATION_REQUEST_NOTIFICATION,
+ "account", account,
+ "authorization-request", request,
+ NULL);
+
+ g_object_get(
+ notification,
+ "authorization-request", &request1,
+ NULL);
+
+ g_assert_true(request1 == request);
+ g_clear_object(&request1);
+
+ g_assert_finalize_object(notification);
+
+ g_clear_object(&request);
+ g_clear_object(&account);
+}
+
+static void
+test_purple_authorization_request_notification_updates_title(void) {
+ PurpleAccount *account = NULL;
+ PurpleAuthorizationRequest *request = NULL;
+ PurpleNotification *notification = NULL;
+ guint counter = 0;
+
+ account = purple_account_new("test", "test");
+ request = purple_authorization_request_new(account, "remote-username");
+
+ notification = purple_authorization_request_notification_new(request);
+ g_signal_connect(notification, "notify::title",
+ G_CALLBACK(test_purple_authorization_request_notification_notify_cb),
+ &counter);
+
+ g_assert_cmpuint(counter, ==, 0);
+
+ purple_authorization_request_set_alias(request, "foo");
+
+ g_assert_cmpuint(counter, ==, 1);
+
+ g_assert_finalize_object(notification);
+
+ g_clear_object(&request);
+ g_clear_object(&account);
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+gint
+main(gint argc, gchar *argv[]) {
+ gint ret = 0;
+
+ g_test_init(&argc, &argv, NULL);
+
+ test_ui_purple_init();
+
+ g_test_add_func("/request-authorization-notification/new",
+ test_purple_authorization_request_notification_new);
+ g_test_add_func("/request-authorization-notification/properties",
+ test_purple_authorization_request_notification_properties);
+ g_test_add_func("/request-authorization-notification/updates-title",
+ test_purple_authorization_request_notification_updates_title);
+
+ ret = g_test_run();
+
+ test_ui_purple_uninit();
+
+ return ret;
+}