# HG changeset patch
# Node ID 71b17254fbe0
# Parent  70d33d4dac09
diff --git a/libpurple/meson.build b/libpurple/meson.build
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -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',
diff --git a/libpurple/purpleauthorizationrequestnotification.h b/libpurple/purpleauthorizationrequestnotification.h
new file mode 100644
--- /dev/null
+++ b/libpurple/purpleauthorizationrequestnotification.h
@@ -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 */
diff --git a/libpurple/purpleauthorizationrequestnotification.c b/libpurple/purpleauthorizationrequestnotification.c
new file mode 100644
--- /dev/null
+++ b/libpurple/purpleauthorizationrequestnotification.c
@@ -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(alias != NULL && *alias != '\0') {
+		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;
+}
diff --git a/libpurple/tests/meson.build b/libpurple/tests/meson.build
--- a/libpurple/tests/meson.build
+++ b/libpurple/tests/meson.build
@@ -2,6 +2,7 @@
     'account_option',
     'account_manager',
     'authorization_request',
+    'authorization_request_notification',
     'channel_join_details',
     'circular_buffer',
     'create_conversation_details',
diff --git a/libpurple/tests/test_authorization_request_notification.c b/libpurple/tests/test_authorization_request_notification.c
new file mode 100644
--- /dev/null
+++ b/libpurple/tests/test_authorization_request_notification.c
@@ -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;
+}
