commit e4c9d144af70ac32960c5f39d1544becea9d427c
parent 6e8ea55e93938882a12ec67a682b83931d975836
Author: Jacki <jacki@thejackimonster.de>
Date: Sun, 16 Jun 2024 18:24:29 +0200
Add panels per active subscription to discourse dialog
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
8 files changed, 308 insertions(+), 20 deletions(-)
diff --git a/resources/ui.gresource.xml b/resources/ui.gresource.xml
@@ -11,6 +11,7 @@
<file compressed="true">ui/contact_info.ui</file>
<file compressed="true">ui/contacts.ui</file>
<file compressed="true">ui/delete_messages.ui</file>
+ <file compressed="true">ui/discourse_panel.ui</file>
<file compressed="true">ui/discourse.ui</file>
<file compressed="true">ui/files.ui</file>
<file compressed="true">ui/file_entry.ui</file>
diff --git a/src/chat/messenger.c b/src/chat/messenger.c
@@ -213,6 +213,26 @@ _chat_messenger_message(void *cls,
application_call_event(app, event_update_attributes);
break;
}
+ case GNUNET_CHAT_KIND_DISCOURSE:
+ {
+ application_call_message_event(
+ app,
+ event_discourse,
+ context,
+ message
+ );
+ break;
+ }
+ case GNUNET_CHAT_KIND_DATA:
+ {
+ application_call_message_event(
+ app,
+ event_discourse_data,
+ context,
+ message
+ );
+ break;
+ }
default:
break;
}
diff --git a/src/event.c b/src/event.c
@@ -1012,3 +1012,24 @@ event_update_attributes(MESSENGER_Application *app)
app
);
}
+
+void
+event_discourse(MESSENGER_Application *app,
+ struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Message *msg)
+{
+ g_assert((app) && (context) && (msg));
+
+ if (context == app->ui.discourse.context)
+ ui_discourse_window_update(&(app->ui.discourse), context);
+}
+
+void
+event_discourse_data(MESSENGER_Application *app,
+ struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Message *msg)
+{
+ g_assert((app) && (context) && (msg));
+
+ // TODO
+}
diff --git a/src/event.h b/src/event.h
@@ -184,4 +184,30 @@ event_tag_message(MESSENGER_Application *app,
void
event_update_attributes(MESSENGER_Application *app);
+/**
+ * Event for the UI to be called whenever a discourse
+ * message gets received in a given context.
+ *
+ * @param app Messenger application
+ * @param context Chat context
+ * @param msg Discourse message
+ */
+void
+event_discourse(MESSENGER_Application *app,
+ struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Message *msg);
+
+/**
+ * Event for the UI to be called whenever a data
+ * message gets received in a given context.
+ *
+ * @param app Messenger application
+ * @param context Chat context
+ * @param msg Data message
+ */
+void
+event_discourse_data(MESSENGER_Application *app,
+ struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Message *msg);
+
#endif /* EVENT_H_ */
diff --git a/src/ui/discourse.c b/src/ui/discourse.c
@@ -29,6 +29,7 @@
#include <gnunet/gnunet_time_lib.h>
#include "account_entry.h"
+#include "discourse_panel.h"
#include "../application.h"
#include "../ui.h"
@@ -110,10 +111,7 @@ handle_call_button_click(UNUSED GtkButton *button,
if (!(handle->context))
return;
- const gboolean calling = (
- (handle->voice_discourse) &&
- (GNUNET_YES == GNUNET_CHAT_discourse_is_open(handle->voice_discourse))
- );
+ const gboolean calling = (handle->voice_discourse? TRUE : FALSE);
struct GNUNET_ShortHashCode voice_id;
memset(&voice_id, 0, sizeof(voice_id));
@@ -299,29 +297,53 @@ ui_discourse_window_init(MESSENGER_Application *app,
gtk_widget_show_all(GTK_WIDGET(handle->window));
}
+struct IterateDiscourseClosure {
+ MESSENGER_Application *app;
+ GtkContainer *container;
+};
+
static enum GNUNET_GenericReturnValue
iterate_ui_discourse_update_discourse_members(void *cls,
const struct GNUNET_CHAT_Discourse *discourse,
struct GNUNET_CHAT_Contact *contact)
{
- UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) cls;
+ struct IterateDiscourseClosure *closure = (
+ (struct IterateDiscourseClosure*) cls
+ );
+
+ GtkFlowBox *flowbox = GTK_FLOW_BOX(closure->container);
+ UI_DISCOURSE_PANEL_Handle* panel = ui_discourse_panel_new(closure->app);
+
+ ui_discourse_panel_set_contact(panel, contact);
+
+ gtk_flow_box_insert(flowbox, panel->panel_box, -1);
+
+ GtkFlowBoxChild *child = GTK_FLOW_BOX_CHILD(
+ gtk_widget_get_parent(panel->panel_box)
+ );
- printf("%s\n", GNUNET_CHAT_contact_get_name(contact));
+ g_object_set_qdata(G_OBJECT(child), closure->app->quarks.data, contact);
+ g_object_set_qdata_full(
+ G_OBJECT(child),
+ closure->app->quarks.ui,
+ panel,
+ (GDestroyNotify) ui_discourse_panel_delete
+ );
return GNUNET_YES;
}
static enum GNUNET_GenericReturnValue
iterate_ui_discourse_update_context_discourses(void *cls,
- UNUSED struct GNUNET_CHAT_Context *context,
+ struct GNUNET_CHAT_Context *context,
struct GNUNET_CHAT_Discourse *discourse)
{
- UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) cls;
+ g_assert((cls) && (context) && (discourse));
GNUNET_CHAT_discourse_iterate_contacts(
discourse,
iterate_ui_discourse_update_discourse_members,
- handle
+ cls
);
return GNUNET_YES;
@@ -332,28 +354,45 @@ _discourse_update_members(UI_DISCOURSE_Handle *handle)
{
g_assert(handle);
+ GList* children = gtk_container_get_children(
+ GTK_CONTAINER(handle->members_flowbox)
+ );
+
+ GList *item = children;
+ while ((item) && (item->next)) {
+ GtkWidget *widget = GTK_WIDGET(item->data);
+ item = item->next;
+
+ gtk_container_remove(
+ GTK_CONTAINER(handle->members_flowbox),
+ widget
+ );
+ }
+
+ if (children)
+ g_list_free(children);
+
if (!(handle->context))
return;
+ struct IterateDiscourseClosure closure;
+ closure.app = handle->app;
+ closure.container = GTK_CONTAINER(handle->members_flowbox);
+
GNUNET_CHAT_context_iterate_discourses(
handle->context,
iterate_ui_discourse_update_context_discourses,
- handle
+ &closure
);
}
-struct IterateChatClosure {
- MESSENGER_Application *app;
- GtkContainer *container;
-};
-
static enum GNUNET_GenericReturnValue
iterate_ui_discourse_update_group_contacts(void *cls,
UNUSED const struct GNUNET_CHAT_Group *group,
struct GNUNET_CHAT_Contact *contact)
{
- struct IterateChatClosure *closure = (
- (struct IterateChatClosure*) cls
+ struct IterateDiscourseClosure *closure = (
+ (struct IterateDiscourseClosure*) cls
);
GtkListBox *listbox = GTK_LIST_BOX(closure->container);
@@ -404,7 +443,7 @@ _discourse_update_contacts(UI_DISCOURSE_Handle *handle,
if (group)
{
- struct IterateChatClosure closure;
+ struct IterateDiscourseClosure closure;
closure.app = handle->app;
closure.container = GTK_CONTAINER(handle->contacts_listbox);
@@ -430,8 +469,6 @@ ui_discourse_window_update(UI_DISCOURSE_Handle *handle,
if (handle->context)
{
// TODO
-
-
}
handle->context = context;
diff --git a/src/ui/discourse_panel.c b/src/ui/discourse_panel.c
@@ -0,0 +1,101 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2024 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/discourse_panel.c
+ */
+
+#include "discourse_panel.h"
+
+#include "../contact.h"
+#include "../ui.h"
+
+UI_DISCOURSE_PANEL_Handle*
+ui_discourse_panel_new(MESSENGER_Application *app)
+{
+ g_assert(app);
+
+ UI_DISCOURSE_PANEL_Handle* handle = g_malloc(sizeof(UI_DISCOURSE_PANEL_Handle));
+
+ handle->contact = NULL;
+
+ handle->builder = ui_builder_from_resource(
+ application_get_resource_path(app, "ui/discourse_panel.ui")
+ );
+
+ handle->panel_box = GTK_WIDGET(
+ gtk_builder_get_object(handle->builder, "panel_box")
+ );
+
+ handle->panel_stack = GTK_STACK(
+ gtk_builder_get_object(handle->builder, "panel_stack")
+ );
+
+ handle->avatar_box = GTK_WIDGET(
+ gtk_builder_get_object(handle->builder, "avatar_box")
+ );
+
+ handle->panel_avatar = HDY_AVATAR(
+ gtk_builder_get_object(handle->builder, "panel_avatar")
+ );
+
+ handle->panel_label = GTK_LABEL(
+ gtk_builder_get_object(handle->builder, "panel_label")
+ );
+
+ handle->video_drawing_area = GTK_DRAWING_AREA(
+ gtk_builder_get_object(handle->builder, "video_drawing_area")
+ );
+
+ return handle;
+}
+
+void
+ui_discourse_panel_set_contact(UI_DISCOURSE_PANEL_Handle* handle,
+ const struct GNUNET_CHAT_Contact *contact)
+{
+ g_assert(handle);
+
+ if (handle->contact)
+ {
+ contact_remove_name_avatar_from_info(handle->contact, handle->panel_avatar);
+ contact_remove_name_label_from_info(handle->contact, handle->panel_label);
+ }
+
+ if (contact)
+ {
+ contact_add_name_avatar_to_info(contact, handle->panel_avatar);
+ contact_add_name_label_to_info(contact, handle->panel_label);
+ }
+
+ handle->contact = contact;
+}
+
+void
+ui_discourse_panel_delete(UI_DISCOURSE_PANEL_Handle *handle)
+{
+ g_assert(handle);
+
+ ui_discourse_panel_set_contact(handle, NULL);
+
+ g_object_unref(handle->builder);
+
+ g_free(handle);
+}
diff --git a/src/ui/discourse_panel.h b/src/ui/discourse_panel.h
@@ -0,0 +1,81 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2024 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/discourse_panel.h
+ */
+
+#ifndef UI_DISCOURSE_PANEL_H_
+#define UI_DISCOURSE_PANEL_H_
+
+#include "messenger.h"
+
+#include <gnunet/gnunet_chat_lib.h>
+
+typedef struct UI_DISCOURSE_PANEL_Handle
+{
+ const struct GNUNET_CHAT_Contact *contact;
+
+ GtkBuilder *builder;
+
+ GtkWidget *panel_box;
+
+ GtkStack *panel_stack;
+ GtkWidget *avatar_box;
+
+ HdyAvatar *panel_avatar;
+ GtkLabel *panel_label;
+
+ GtkDrawingArea *video_drawing_area;
+} UI_DISCOURSE_PANEL_Handle;
+
+/**
+ * Allocates and creates a new discourse panel
+ * handle to visualize a contact in a discourse
+ * a given messenger application.
+ *
+ * @param app Messenger application
+ * @return New discourse panel handle
+ */
+UI_DISCOURSE_PANEL_Handle*
+ui_discourse_panel_new(MESSENGER_Application *app);
+
+/**
+ * Sets the content of the given discourse panel
+ * handle respectively to visually represent a
+ * selected chat contact.
+ *
+ * @param handle Discourse panel handle
+ * @param contact Chat contact
+ */
+void
+ui_discourse_panel_set_contact(UI_DISCOURSE_PANEL_Handle* handle,
+ const struct GNUNET_CHAT_Contact *contact);
+
+/**
+ * Frees its resources and destroys a given
+ * discourse panel handle.
+ *
+ * @param handle Discourse panel handle
+ */
+void
+ui_discourse_panel_delete(UI_DISCOURSE_PANEL_Handle *handle);
+
+#endif /* UI_DISCOURSE_PANEL_H_ */
diff --git a/src/ui/meson.build b/src/ui/meson.build
@@ -29,6 +29,7 @@ messenger_gtk_ui_sources = files([
'contact_info.c', 'contact_info.h',
'contacts.c', 'contacts.h',
'delete_messages.c', 'delete_messages.h',
+ 'discourse_panel.c', 'discourse_panel.h',
'discourse.c', 'discourse.h',
'files.c', 'files.h',
'file_entry.c', 'file_entry.h',