commit 35f830ec5f9ea6ff42d2c98e2a0efb40de3dd1f2
parent d71038500f255d3e5b491eea0677d179866044d2
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Sun, 19 Dec 2021 15:07:25 +0100
Added dialog to invite contact to group
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
6 files changed, 385 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,6 +12,7 @@ SOURCES = messenger_gtk.c\
ui/chat_entry.c\
ui/contact_entry.c\
ui/contacts.c\
+ ui/invite_contact.c\
ui/message.c\
ui/messenger.c\
ui/new_contact.c\
diff --git a/resources/ui/invite_contact.ui b/resources/ui/invite_contact.ui
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2
+
+Copyright (C) 2021 GNUnet e.V.
+
+GNUnet is free software: you can redistribute it and/or modify it
+under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License,
+or (at your option) any later version.
+
+GNUnet 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
+Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+SPDX-License-Identifier: AGPL3.0-or-later
+Author: Tobias Frisch
+
+-->
+<interface>
+ <requires lib="gtk+" version="3.24"/>
+ <object class="GtkDialog" id="invite_contact_dialog">
+ <property name="can-focus">False</property>
+ <property name="modal">True</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="close_button">
+ <property name="label" translatable="yes">Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSearchEntry" id="contact_search_entry">
+ <property name="width-request">250</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="primary-icon-name">edit-find-symbolic</property>
+ <property name="primary-icon-activatable">False</property>
+ <property name="primary-icon-sensitive">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="height-request">200</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkListBox" id="contacts_listbox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/application.h b/src/application.h
@@ -31,6 +31,7 @@
#include "chat/messenger.h"
#include "ui/contacts.h"
+#include "ui/invite_contact.h"
#include "ui/messenger.h"
#include "ui/new_contact.h"
#include "ui/new_group.h"
@@ -73,6 +74,7 @@ typedef struct MESSENGER_Application
UI_MESSENGER_Handle messenger;
+ UI_INVITE_CONTACT_Handle invite_contact;
UI_SEND_FILE_Handle send_file;
UI_NEW_CONTACT_Handle new_contact;
diff --git a/src/ui/chat.c b/src/ui/chat.c
@@ -47,15 +47,30 @@ handle_flap_via_button_click(UNUSED GtkButton *button,
}
static void
-handle_chat_contacts_listbox_row_activated(UNUSED GtkListBox *listbox,
+handle_chat_contacts_listbox_row_activated(GtkListBox *listbox,
GtkListBoxRow *row,
gpointer user_data)
{
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
+ GtkTextView *text_view = GTK_TEXT_VIEW(
+ g_hash_table_lookup(app->ui.bindings, listbox)
+ );
+
+ if (!text_view)
+ return;
+
if (!gtk_list_box_row_get_selectable(row))
{
- //g_idle_add(G_SOURCE_FUNC(_open_new_contact_dialog), app);
+ ui_invite_contact_dialog_init(app, &(app->ui.invite_contact));
+
+ g_hash_table_insert(
+ app->ui.bindings,
+ app->ui.invite_contact.contacts_listbox,
+ text_view
+ );
+
+ gtk_widget_show(GTK_WIDGET(app->ui.invite_contact.dialog));
return;
}
@@ -375,6 +390,12 @@ ui_chat_new(MESSENGER_Application *app)
g_hash_table_insert(
app->ui.bindings,
+ handle->chat_contacts_listbox,
+ handle->send_text_view
+ );
+
+ g_hash_table_insert(
+ app->ui.bindings,
handle->attach_file_button,
handle->send_text_view
);
diff --git a/src/ui/invite_contact.c b/src/ui/invite_contact.c
@@ -0,0 +1,206 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet 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
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file ui/invite_contact.c
+ */
+
+#include "invite_contact.h"
+
+#include "chat_entry.h"
+#include "contact_entry.h"
+#include "../application.h"
+
+static void
+handle_close_button_click(UNUSED GtkButton *button,
+ gpointer user_data)
+{
+ GtkDialog *dialog = GTK_DIALOG(user_data);
+ gtk_window_close(GTK_WINDOW(dialog));
+}
+
+static void
+handle_contacts_listbox_row_activated(GtkListBox* listbox,
+ GtkListBoxRow* row,
+ gpointer user_data)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) user_data;
+
+ GtkTextView *text_view = GTK_TEXT_VIEW(
+ g_hash_table_lookup(app->ui.bindings, listbox)
+ );
+
+ struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
+ g_hash_table_lookup(app->ui.bindings, row)
+ );
+
+ if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
+ (GNUNET_YES == GNUNET_CHAT_contact_is_owned(contact)) ||
+ (!text_view))
+ goto close_dialog;
+
+ struct GNUNET_CHAT_Context *context = g_hash_table_lookup(
+ app->ui.bindings, text_view
+ );
+
+ if (!context)
+ goto close_dialog;
+
+ const struct GNUNET_CHAT_Group *group = GNUNET_CHAT_context_get_group(
+ context
+ );
+
+ if (group)
+ GNUNET_CHAT_group_invite_contact(group, contact);
+
+close_dialog:
+ gtk_window_close(GTK_WINDOW(app->ui.invite_contact.dialog));
+}
+
+static void
+handle_dialog_destroy(UNUSED GtkWidget *window,
+ gpointer user_data)
+{
+ ui_contacts_dialog_cleanup((UI_CONTACTS_Handle*) user_data);
+}
+
+static int
+_iterate_contacts(void *cls,
+ UNUSED struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_CHAT_Contact *contact)
+{
+ if (GNUNET_YES == GNUNET_CHAT_contact_is_owned(contact))
+ return GNUNET_YES;
+
+ MESSENGER_Application *app = (MESSENGER_Application*) cls;
+
+ const char *title;
+ title = GNUNET_CHAT_contact_get_name(contact);
+
+ const char *key = GNUNET_CHAT_contact_get_key(contact);
+
+ UI_CONTACT_ENTRY_Handle *entry = ui_contact_entry_new();
+ gtk_list_box_prepend(
+ app->ui.invite_contact.contacts_listbox,
+ entry->entry_box
+ );
+
+ if (title)
+ {
+ gtk_label_set_text(entry->title_label, title);
+ hdy_avatar_set_text(entry->entry_avatar, title);
+ }
+
+ if (key)
+ gtk_label_set_text(entry->subtitle_label, key);
+
+ GtkListBoxRow *row = GTK_LIST_BOX_ROW(
+ gtk_widget_get_parent(entry->entry_box)
+ );
+
+ g_hash_table_insert(app->ui.bindings, row, contact);
+
+ app->ui.invite_contact.contact_entries = g_list_append(
+ app->ui.invite_contact.contact_entries,
+ entry
+ );
+
+ return GNUNET_YES;
+}
+
+void
+ui_invite_contact_dialog_init(MESSENGER_Application *app,
+ UI_INVITE_CONTACT_Handle *handle)
+{
+ handle->contact_entries = NULL;
+
+ handle->builder = gtk_builder_new_from_file("resources/ui/invite_contact.ui");
+
+ handle->dialog = GTK_DIALOG(
+ gtk_builder_get_object(handle->builder, "invite_contact_dialog")
+ );
+
+ gtk_window_set_title(
+ GTK_WINDOW(handle->dialog),
+ _("Invite Contact")
+ );
+
+ gtk_window_set_transient_for(
+ GTK_WINDOW(handle->dialog),
+ GTK_WINDOW(app->ui.messenger.main_window)
+ );
+
+ handle->contact_search_entry = GTK_SEARCH_ENTRY(
+ gtk_builder_get_object(handle->builder, "contact_search_entry")
+ );
+
+ handle->contacts_listbox = GTK_LIST_BOX(
+ gtk_builder_get_object(handle->builder, "contacts_listbox")
+ );
+
+ g_signal_connect(
+ handle->contacts_listbox,
+ "row-activated",
+ G_CALLBACK(handle_contacts_listbox_row_activated),
+ app
+ );
+
+ handle->close_button = GTK_BUTTON(
+ gtk_builder_get_object(handle->builder, "close_button")
+ );
+
+ g_signal_connect(
+ handle->close_button,
+ "clicked",
+ G_CALLBACK(handle_close_button_click),
+ handle->dialog
+ );
+
+ g_signal_connect(
+ handle->dialog,
+ "destroy",
+ G_CALLBACK(handle_dialog_destroy),
+ handle
+ );
+
+ GNUNET_CHAT_iterate_contacts(
+ app->chat.messenger.handle,
+ _iterate_contacts,
+ app
+ );
+}
+
+void
+ui_invite_contact_dialog_cleanup(UI_INVITE_CONTACT_Handle *handle)
+{
+ g_object_unref(handle->builder);
+
+ GList *list = handle->contact_entries;
+
+ while (list) {
+ if (list->data)
+ ui_contact_entry_delete((UI_CONTACT_ENTRY_Handle*) list->data);
+
+ list = list->next;
+ }
+
+ if (handle->contact_entries)
+ g_list_free(handle->contact_entries);
+}
diff --git a/src/ui/invite_contact.h b/src/ui/invite_contact.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet 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
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file ui/invite_contact.h
+ */
+
+#ifndef UI_INVITE_CONTACT_H_
+#define UI_INVITE_CONTACT_H_
+
+#include "messenger.h"
+
+typedef struct UI_INVITE_CONTACT_Handle
+{
+ GList *contact_entries;
+
+ GtkBuilder *builder;
+ GtkDialog *dialog;
+
+ GtkSearchEntry *contact_search_entry;
+
+ GtkListBox *contacts_listbox;
+
+ GtkButton *close_button;
+} UI_INVITE_CONTACT_Handle;
+
+void
+ui_invite_contact_dialog_init(MESSENGER_Application *app,
+ UI_INVITE_CONTACT_Handle *handle);
+
+void
+ui_invite_contact_dialog_cleanup(UI_INVITE_CONTACT_Handle *handle);
+
+#endif /* UI_INVITE_CONTACT_H_ */