]> www.infradead.org Git - pidgin-chime.git/commitdiff
Add user search UI
authorDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 11 Aug 2017 13:29:58 +0000 (14:29 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 11 Aug 2017 13:29:58 +0000 (14:29 +0100)
buddy.c
chime.c
chime.h

diff --git a/buddy.c b/buddy.c
index e3fc4a3a4d432f9e080bb6b58f4d182adfdcd281..a0d3647fa87b2633087e5db34c42ef565a85a3f3 100644 (file)
--- a/buddy.c
+++ b/buddy.c
@@ -22,6 +22,7 @@
 
 #include <prpl.h>
 #include <blist.h>
+#include <request.h>
 
 #include "chime.h"
 
@@ -193,4 +194,143 @@ void chime_purple_remove_buddy(PurpleConnection *conn, PurpleBuddy *buddy, Purpl
        chime_connection_remove_contact_async(cxn, buddy->name,
                                              NULL, on_buddy_removed, conn);
 }
+static void search_add_buddy(PurpleConnection *conn, GList *row, gpointer _unused)
+{
+       purple_blist_request_add_buddy(purple_connection_get_account(conn),
+                                      g_list_nth_data(row, 1), NULL, NULL);
+}
+
+static void search_im(PurpleConnection *conn, GList *row, gpointer _unused)
+{
+       PurpleConversation *conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, purple_connection_get_account(conn),
+                                                          g_list_nth_data(row, 1));
+       purple_conversation_present(conv);
+}
+
+struct search_data {
+       PurpleConnection *conn;
+       void *ui_handle;
+       GSList *contacts;
+       guint refresh_id;
+};
+
+static PurpleNotifySearchResults *generate_search_results(GSList *contacts)
+{
+       PurpleNotifySearchResults *results = purple_notify_searchresults_new();
+       PurpleNotifySearchColumn *column;
+
+       column = purple_notify_searchresults_column_new(_("Name"));
+       purple_notify_searchresults_column_add(results, column);
+       column = purple_notify_searchresults_column_new(_("Email"));
+       purple_notify_searchresults_column_add(results, column);
+       column = purple_notify_searchresults_column_new(_("Availability"));
+       purple_notify_searchresults_column_add(results, column);
+
+       purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_ADD,
+                                              search_add_buddy);
+       purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_IM,
+                                              search_im);
+
+       gpointer klass = g_type_class_ref(CHIME_TYPE_AVAILABILITY);
+
+       while (contacts) {
+               ChimeContact *contact = contacts->data;
+               GList *row = NULL;
+               row = g_list_append(row, g_strdup(chime_contact_get_display_name(contact)));
+               row = g_list_append(row, g_strdup(chime_contact_get_email(contact)));
+               GEnumValue *val = g_enum_get_value(klass, chime_contact_get_availability(contact));
+               row = g_list_append(row, g_strdup(_(val->value_nick)));
+               purple_notify_searchresults_row_add(results, row);
+               contacts = contacts->next;
+       }
+
+       g_type_class_unref(klass);
+       return results;
+}
+
+static void search_closed_cb(gpointer _sd)
+{
+       struct search_data *sd = _sd;
+
+       if (sd->refresh_id)
+               g_source_remove(sd->refresh_id);
+       while (sd->contacts) {
+               ChimeContact *contact = sd->contacts->data;
+               g_signal_handlers_disconnect_matched(contact, G_SIGNAL_MATCH_DATA,
+                                                    0, 0, NULL, NULL, sd);
+               g_object_unref(contact);
+               sd->contacts = g_slist_remove(sd->contacts, contact);
+       }
+       g_free(sd);
+}
+
+static gboolean renew_search_results(gpointer _sd)
+{
+       struct search_data *sd = _sd;
+
+       PurpleNotifySearchResults *results = generate_search_results(sd->contacts);
+       purple_notify_searchresults_new_rows(sd->conn, results, sd->ui_handle);
+
+       sd->refresh_id = 0;
+       return FALSE;
+}
 
+static void on_search_availability(ChimeContact *contact, GParamSpec *ignored, struct search_data *sd)
+{
+       /* Gather them up to avoid repeatedly redrawing as they come in the first time */
+       if (!sd->refresh_id)
+               sd->refresh_id = g_idle_add(renew_search_results, sd);
+}
+
+static void search_done(GObject *source, GAsyncResult *result, gpointer _conn)
+{
+       PurpleConnection *conn = _conn;
+       GError *error = NULL;
+       GSList *contacts = chime_connection_autocomplete_contact_finish(CHIME_CONNECTION(source), result, &error);
+
+       if (error) {
+               g_warning("Autocomplete failed: %s\n", error->message);
+               g_error_free(error);
+               return;
+       }
+
+       PurpleNotifySearchResults *results = generate_search_results(contacts);
+
+       struct search_data *sd = g_new0(struct search_data, 1);
+       sd->contacts = contacts;
+       sd->conn = conn;
+       sd->ui_handle = purple_notify_searchresults(conn, _("Chime autocomplete"), _("Search results"),
+                                                   NULL, results, search_closed_cb, sd);
+       if (!sd->ui_handle) {
+               purple_notify_error(conn, NULL,
+                                   _("Unable to display search results."),
+                                   NULL);
+               search_closed_cb(sd);
+               return;
+       }
+       /* Strictly speaking we don't own these now but we know we're single-threaded */
+       while (contacts) {
+               ChimeContact *contact = contacts->data;
+               g_signal_connect(contact, "notify::availability",
+                                G_CALLBACK(on_search_availability), sd);
+               contacts = contacts->next;
+       }
+}
+
+static void user_search_begin(PurpleConnection *conn, const char *query)
+{
+       ChimeConnection *cxn = PURPLE_CHIME_CXN(conn);
+
+       chime_connection_autocomplete_contact_async(cxn, query, NULL, search_done, conn);
+}
+
+void chime_purple_user_search(PurplePluginAction *action)
+{
+       PurpleConnection *conn = (PurpleConnection *) action->context;
+       purple_request_input(conn, _("Chime user lookup"),
+                            _("Enter the user information to lookup"), NULL, NULL,
+                            FALSE, FALSE, NULL,
+                            _("Search"), PURPLE_CALLBACK(user_search_begin),
+                            _("Cancel"), NULL,
+                            NULL, NULL, NULL, conn);
+}
diff --git a/chime.c b/chime.c
index 63d831c0cd22794056f69f201ff69ae5a303d30c..89ee57a99436105fea4f378d445d3407a265903f 100644 (file)
--- a/chime.c
+++ b/chime.c
@@ -337,11 +337,15 @@ static GList *chime_purple_plugin_actions(PurplePlugin *plugin,
 {
        PurplePluginAction *act;
        GList *acts = NULL;
-       printf("chime acts\n");
+
        act = purple_plugin_action_new(_("About Chime plugin..."),
                                       chime_purple_show_about_plugin);
        acts = g_list_append(acts, act);
 
+       act = purple_plugin_action_new(_("User search..."),
+                                      chime_purple_user_search);
+       acts = g_list_append(acts, act);
+
        return acts;
 }
 
diff --git a/chime.h b/chime.h
index cd8af51fa0d121a2c238a61b9697fed2d396c37d..8185dbfb59ce7b6758eb2f5ad274f2f128cffc48 100644 (file)
--- a/chime.h
+++ b/chime.h
@@ -98,6 +98,7 @@ void chime_purple_add_buddy(PurpleConnection *conn, PurpleBuddy *buddy, PurpleGr
 void chime_purple_remove_buddy(PurpleConnection *conn, PurpleBuddy *buddy, PurpleGroup *group);
 void chime_init_buddies(ChimeConnection *cxn);
 void chime_destroy_buddies(ChimeConnection *cxn);
+void chime_purple_user_search(PurplePluginAction *action);
 
 /* rooms.c */
 PurpleRoomlist *chime_purple_roomlist_get_list(PurpleConnection *conn);