messenger-gtk

Gtk+3 graphical user interfaces for GNUnet Messenger
Log | Files | Refs | Submodules | README | LICENSE

commit 5df934d452aaedf319028740987de0e0dcac52d5
parent 724f7738ed6d60bccabb428c2ae87faba9033b0c
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Wed, 24 Nov 2021 03:18:23 +0100

Added invitations for private chats and cleaned up status messages

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
Mresources/css/style.css | 2+-
Mresources/ui/message-sent.ui | 3---
Mresources/ui/message-status.ui | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mresources/ui/message.ui | 3---
Msrc/application.c | 62+++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/application.h | 23+++++++++++++++++------
Msrc/chat/messenger.c | 45+++++++++++++++++++++++++++++++++------------
Msrc/event.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/event.h | 21++++++++++++---------
Msrc/ui/message.c | 42++++++++++++++++++++++++++++++++++++------
Msrc/ui/message.h | 14+++++++++++++-
11 files changed, 369 insertions(+), 98 deletions(-)

diff --git a/resources/css/style.css b/resources/css/style.css @@ -58,7 +58,7 @@ } .message-box.status > .message-content { - padding: 2px 12px; + padding: 2px 4px; } .settings-entry { diff --git a/resources/ui/message-sent.ui b/resources/ui/message-sent.ui @@ -59,7 +59,6 @@ Author: Tobias Frisch <object class="GtkLabel" id="text_label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">My evil comment text is awesome! This is coming to the Pinephone which will be extremely awesome and this text may only cut some borders in certain areas!!!</property> <property name="wrap">True</property> <property name="max-width-chars">64</property> <property name="xalign">0</property> @@ -92,7 +91,6 @@ Author: Tobias Frisch <object class="GtkLabel" id="timestamp_label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">0min</property> <attributes> <attribute name="weight" value="light"/> </attributes> @@ -120,7 +118,6 @@ Author: Tobias Frisch <object class="GtkLabel" id="sender_label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">User</property> <attributes> <attribute name="weight" value="semibold"/> </attributes> diff --git a/resources/ui/message-status.ui b/resources/ui/message-status.ui @@ -22,7 +22,8 @@ Author: Tobias Frisch --> <interface> <requires lib="gtk+" version="3.24"/> - <object class="GtkBox"> + <requires lib="libhandy" version="1.2"/> + <object class="GtkBox" id="message_box"> <property name="visible">True</property> <property name="can-focus">False</property> <child> @@ -36,17 +37,113 @@ Author: Tobias Frisch <object class="GtkBox"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="orientation">vertical</property> + <property name="spacing">8</property> <child> - <object class="GtkLabel" id="status_label"> + <object class="GtkButton" id="deny_button"> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="relief">none</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">edit-delete-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">status information</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="text_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">invited you to a chat</property> + <property name="justify">center</property> + <property name="wrap">True</property> + <property name="xalign">0.5</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">4</property> + <child> + <object class="GtkImage" id="read_receipt_image"> + <property name="can-focus">False</property> + <property name="xalign">1</property> + <property name="icon-name">emblem-default-symbolic</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="timestamp_label"> + <property name="can-focus">False</property> + <property name="justify">right</property> + <property name="xalign">1</property> + <attributes> + <attribute name="weight" value="light"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="accept_button"> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="relief">none</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">emblem-ok-symbolic</property> + </object> + </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="pack-type">end</property> + <property name="position">2</property> </packing> </child> <style> @@ -55,13 +152,36 @@ Author: Tobias Frisch </object> </child> <child type="label"> - <object class="GtkLabel" id="sender_label"> + <object class="GtkBox"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">User</property> - <attributes> - <attribute name="weight" value="semibold"/> - </attributes> + <property name="spacing">4</property> + <child> + <object class="HdyAvatar" id="sender_avatar"> + <property name="can-focus">False</property> + <property name="size">24</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="sender_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="xalign">0</property> + <attributes> + <attribute name="weight" value="semibold"/> + </attributes> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> </child> <style> diff --git a/resources/ui/message.ui b/resources/ui/message.ui @@ -58,7 +58,6 @@ Author: Tobias Frisch <object class="GtkLabel" id="text_label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">My evil comment text is awesome! This is coming to the Pinephone which will be extremely awesome and this text may only cut some borders in certain areas!!!</property> <property name="wrap">True</property> <property name="max-width-chars">64</property> <property name="xalign">0</property> @@ -90,7 +89,6 @@ Author: Tobias Frisch <object class="GtkLabel" id="timestamp_label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">0min</property> <attributes> <attribute name="weight" value="light"/> </attributes> @@ -118,7 +116,6 @@ Author: Tobias Frisch <object class="GtkLabel" id="sender_label"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">User</property> <attributes> <attribute name="weight" value="semibold"/> </attributes> diff --git a/src/application.c b/src/application.c @@ -170,8 +170,6 @@ typedef struct MESSENGER_ApplicationEventCall { MESSENGER_Application *app; MESSENGER_ApplicationEvent event; - int argc; - void **argv; } MESSENGER_ApplicationEventCall; static gboolean @@ -180,10 +178,7 @@ _application_event_call(gpointer user_data) MESSENGER_ApplicationEventCall *call; call = (MESSENGER_ApplicationEventCall*) user_data; - call->event(call->app, call->argc, call->argv); - - if (call->argc > 0) - GNUNET_free(call->argv); + call->event(call->app); GNUNET_free(call); return FALSE; @@ -191,9 +186,7 @@ _application_event_call(gpointer user_data) void application_call_event(MESSENGER_Application *app, - MESSENGER_ApplicationEvent event, - int argc, - void **argv) + MESSENGER_ApplicationEvent event) { MESSENGER_ApplicationEventCall *call; @@ -203,19 +196,50 @@ application_call_event(MESSENGER_Application *app, call->app = app; call->event = event; - call->argc = argc; - call->argv = NULL; - if (call->argc > 0) - { - call->argv = GNUNET_new_array(call->argc, void*); + g_idle_add(G_SOURCE_FUNC(_application_event_call), call); +} - for (int i = 0; i < call->argc; i++) { - call->argv[i] = argv[i]; - } - } +typedef struct MESSENGER_ApplicationMessageEventCall +{ + MESSENGER_Application *app; + MESSENGER_ApplicationMessageEvent event; - g_idle_add(G_SOURCE_FUNC(_application_event_call), call); + struct GNUNET_CHAT_Context *context; + const struct GNUNET_CHAT_Message *message; +} MESSENGER_ApplicationMessageEventCall; + +static gboolean +_application_message_event_call(gpointer user_data) +{ + MESSENGER_ApplicationMessageEventCall *call; + + call = (MESSENGER_ApplicationMessageEventCall*) user_data; + call->event(call->app, call->context, call->message); + + GNUNET_free(call); + return FALSE; +} + +void +application_call_message_event(MESSENGER_Application *app, + MESSENGER_ApplicationMessageEvent event, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message) +{ + MESSENGER_ApplicationMessageEventCall *call; + + call = (MESSENGER_ApplicationMessageEventCall*) GNUNET_malloc( + sizeof(MESSENGER_ApplicationMessageEventCall) + ); + + call->app = app; + call->event = event; + + call->context = context; + call->message = message; + + g_idle_add(G_SOURCE_FUNC(_application_message_event_call), call); } void diff --git a/src/application.h b/src/application.h @@ -26,6 +26,7 @@ #define APPLICATION_H_ #include <pthread.h> +#include <gnunet/gnunet_chat_lib.h> #include "chat/messenger.h" @@ -84,15 +85,25 @@ application_init(MESSENGER_Application *app, void application_run(MESSENGER_Application *app); -typedef void (*MESSENGER_ApplicationEvent) (MESSENGER_Application *app, - int argc, - void **argv); +typedef void (*MESSENGER_ApplicationEvent) ( + MESSENGER_Application *app +); + +typedef void (*MESSENGER_ApplicationMessageEvent) ( + MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg +); void application_call_event(MESSENGER_Application *app, - MESSENGER_ApplicationEvent event, - int argc, - void **argv); + MESSENGER_ApplicationEvent event); + +void +application_call_message_event(MESSENGER_Application *app, + MESSENGER_ApplicationMessageEvent event, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message); void application_exit(MESSENGER_Application *app, diff --git a/src/chat/messenger.c b/src/chat/messenger.c @@ -75,30 +75,51 @@ _chat_messenger_message(void *cls, { case GNUNET_CHAT_KIND_LOGIN: { - application_call_event(app, event_update_profile, 0, NULL); + application_call_event(app, event_update_profile); break; } case GNUNET_CHAT_KIND_JOIN: { - if (GNUNET_YES == GNUNET_CHAT_message_is_sent(message)) - application_call_event(app, event_update_chats, 1, (void**) &context); - else - { - void* event_data [2] = { context, &message }; - application_call_event(app, event_joining_contact, 2, event_data); - } - + application_call_message_event( + app, + (GNUNET_YES == GNUNET_CHAT_message_is_sent(message)? + event_update_chats : + event_joining_contact + ), + context, + message + ); + break; + } + case GNUNET_CHAT_KIND_LEAVE: + { + // TODO: add status message break; } case GNUNET_CHAT_KIND_CONTACT: { - + // TODO: update messages and content related to a contacts information + // (name and key) + break; + } + case GNUNET_CHAT_KIND_INVITATION: + { + application_call_message_event( + app, + event_invitation, + context, + message + ); break; } case GNUNET_CHAT_KIND_TEXT: { - void* event_data [2] = { context, &message }; - application_call_event(app, event_receive_message, 2, event_data); + application_call_message_event( + app, + event_receive_message, + context, + message + ); break; } default: diff --git a/src/event.c b/src/event.c @@ -117,9 +117,7 @@ _clear_each_widget(GtkWidget *widget, } void -event_update_profile(MESSENGER_Application *app, - UNUSED int argc, - UNUSED void **argv) +event_update_profile(MESSENGER_Application *app) { UI_MESSENGER_Handle *ui = &(app->ui.messenger); CHAT_MESSENGER_Handle *chat = &(app->chat.messenger); @@ -164,14 +162,9 @@ event_update_profile(MESSENGER_Application *app, void event_update_chats(MESSENGER_Application *app, - int argc, - void **argv) + struct GNUNET_CHAT_Context *context, + UNUSED const struct GNUNET_CHAT_Message *msg) { - if (argc < 1) - return; - - struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) argv[0]; - if (GNUNET_CHAT_context_get_user_pointer(context)) return; @@ -180,46 +173,109 @@ event_update_chats(MESSENGER_Application *app, void event_joining_contact(MESSENGER_Application *app, - int argc, - void **argv) + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg) { - if (argc < 2) + UI_CHAT_ENTRY_Handle *handle = GNUNET_CHAT_context_get_user_pointer(context); + + if (!handle) return; - struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) argv[0]; + UI_MESSAGE_Handle *message = ui_message_new(app, UI_MESSAGE_STATUS); + + const struct GNUNET_CHAT_Contact *contact = GNUNET_CHAT_message_get_sender( + msg + ); + + const char *sender = GNUNET_CHAT_contact_get_name(contact); + + hdy_avatar_set_text(message->sender_avatar, sender? sender : ""); + gtk_label_set_text(message->sender_label, sender? sender : ""); + + gtk_label_set_text(message->text_label, "joined the chat"); + + gtk_container_add( + GTK_CONTAINER(handle->chat->messages_listbox), + message->message_box + ); + + ui_message_delete(message); +} + +static void +_event_invitation_accept_click(UNUSED GtkButton *button, + gpointer user_data) +{ + struct GNUNET_CHAT_Invitation *invitation = ( + (struct GNUNET_CHAT_Invitation*) user_data + ); + + GNUNET_CHAT_invitation_accept(invitation); +} +void +event_invitation(MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg) +{ UI_CHAT_ENTRY_Handle *handle = GNUNET_CHAT_context_get_user_pointer(context); if (!handle) return; - const struct GNUNET_CHAT_Message *msg; - msg = *((const struct GNUNET_CHAT_Message**) argv[1]); + struct GNUNET_CHAT_Invitation *invitation; + invitation = GNUNET_CHAT_message_get_invitation(msg); + + if (!invitation) + return; + + UI_MESSAGE_Handle *message = ui_message_new(app, UI_MESSAGE_STATUS); + + const struct GNUNET_CHAT_Contact *contact = GNUNET_CHAT_message_get_sender( + msg + ); + + const char *sender = GNUNET_CHAT_contact_get_name(contact); + + hdy_avatar_set_text(message->sender_avatar, sender? sender : ""); + gtk_label_set_text(message->sender_label, sender? sender : ""); + + gtk_label_set_text(message->text_label, "invited you to a chat"); + + g_signal_connect( + message->accept_button, + "clicked", + G_CALLBACK(_event_invitation_accept_click), + invitation + ); + + gtk_widget_show(GTK_WIDGET(message->deny_button)); + gtk_widget_show(GTK_WIDGET(message->accept_button)); + + gtk_container_add( + GTK_CONTAINER(handle->chat->messages_listbox), + message->message_box + ); - // + ui_message_delete(message); } void event_receive_message(MESSENGER_Application *app, - int argc, - void **argv) + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg) { - if (argc < 2) - return; - - struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) argv[0]; - UI_CHAT_ENTRY_Handle *handle = GNUNET_CHAT_context_get_user_pointer(context); if (!handle) return; - const struct GNUNET_CHAT_Message *msg; - msg = *((const struct GNUNET_CHAT_Message**) argv[1]); - const int sent = GNUNET_CHAT_message_is_sent(msg); - UI_MESSAGE_Handle *message = ui_message_new(app, GNUNET_YES == sent); + UI_MESSAGE_Handle *message = ui_message_new( + app, + GNUNET_YES == sent? UI_MESSAGE_SENT : UI_MESSAGE_DEFAULT + ); if (GNUNET_YES != sent) { diff --git a/src/event.h b/src/event.h @@ -28,23 +28,26 @@ #include "application.h" void -event_update_profile(MESSENGER_Application *app, - int argc, - void **argv); +event_update_profile(MESSENGER_Application *app); void event_update_chats(MESSENGER_Application *app, - int argc, - void **argv); + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg); void event_joining_contact(MESSENGER_Application *app, - int argc, - void **argv); + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg); + +void +event_invitation(MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg); void event_receive_message(MESSENGER_Application *app, - int argc, - void **argv); + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg); #endif /* EVENT_H_ */ diff --git a/src/ui/message.c b/src/ui/message.c @@ -28,14 +28,28 @@ UI_MESSAGE_Handle* ui_message_new(MESSENGER_Application *app, - bool sent) + UI_MESSAGE_Type type) { UI_MESSAGE_Handle* handle = g_malloc(sizeof(UI_MESSAGE_Handle)); - if (sent) - handle->builder = gtk_builder_new_from_file("resources/ui/message-sent.ui"); - else - handle->builder = gtk_builder_new_from_file("resources/ui/message.ui"); + handle->type = type; + + const char *ui_builder_file; + + switch (handle->type) + { + case UI_MESSAGE_SENT: + ui_builder_file = "resources/ui/message-sent.ui"; + break; + case UI_MESSAGE_STATUS: + ui_builder_file = "resources/ui/message-status.ui"; + break; + default: + ui_builder_file = "resources/ui/message.ui"; + break; + } + + handle->builder = gtk_builder_new_from_file(ui_builder_file); handle->message_box = GTK_WIDGET( gtk_builder_get_object(handle->builder, "message_box") @@ -49,7 +63,7 @@ ui_message_new(MESSENGER_Application *app, gtk_builder_get_object(handle->builder, "sender_label") ); - if (sent) + if (UI_MESSAGE_SENT == handle->type) { const char *sender = GNUNET_CHAT_get_name(app->chat.messenger.handle); @@ -61,6 +75,22 @@ ui_message_new(MESSENGER_Application *app, gtk_builder_get_object(handle->builder, "text_label") ); + if (UI_MESSAGE_STATUS == handle->type) + { + handle->deny_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "deny_button") + ); + + handle->accept_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "accept_button") + ); + } + else + { + handle->deny_button = NULL; + handle->accept_button = NULL; + } + handle->timestamp_label = GTK_LABEL( gtk_builder_get_object(handle->builder, "timestamp_label") ); diff --git a/src/ui/message.h b/src/ui/message.h @@ -32,8 +32,17 @@ typedef struct MESSENGER_Application MESSENGER_Application; +typedef enum UI_MESSAGE_Type +{ + UI_MESSAGE_DEFAULT = 0, + UI_MESSAGE_SENT = 1, + UI_MESSAGE_STATUS = 2 +} UI_MESSAGE_Type; + typedef struct UI_MESSAGE_Handle { + UI_MESSAGE_Type type; + GtkBuilder *builder; GtkWidget *message_box; @@ -42,13 +51,16 @@ typedef struct UI_MESSAGE_Handle GtkLabel *text_label; + GtkButton *deny_button; + GtkButton *accept_button; + GtkLabel *timestamp_label; GtkImage *read_receipt_image; } UI_MESSAGE_Handle; UI_MESSAGE_Handle* ui_message_new(MESSENGER_Application *app, - bool sent); + UI_MESSAGE_Type type); void ui_message_delete(UI_MESSAGE_Handle *handle);