messenger-gtk

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

commit b085cf0e3025a513ebd8e5ff072f0a1fc19210f7
parent 4647c3361fa682e2de8f513442b41861ccfae77b
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Sun, 14 Nov 2021 00:38:00 +0100

Implemented actual sending and receiving of text messages via chat interface

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

Diffstat:
Mresources/ui/message-sent.ui | 1+
Mresources/ui/message.ui | 1+
Msrc/application.c | 27+++++++++++++++++++++++----
Msrc/application.h | 8++++++--
Msrc/chat/messenger.c | 19+++++++++++++------
Msrc/event.c | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/event.h | 11+++++++++--
Msrc/ui/messenger.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++--------
8 files changed, 175 insertions(+), 25 deletions(-)

diff --git a/resources/ui/message-sent.ui b/resources/ui/message-sent.ui @@ -62,6 +62,7 @@ Author: Tobias Frisch <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> </object> <packing> <property name="expand">True</property> diff --git a/resources/ui/message.ui b/resources/ui/message.ui @@ -61,6 +61,7 @@ Author: Tobias Frisch <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> </object> <packing> <property name="expand">True</property> diff --git a/src/application.c b/src/application.c @@ -79,6 +79,8 @@ application_init(MESSENGER_Application *app, app->ui.mobile = FALSE; + app->ui.bindings = g_hash_table_new(g_direct_hash, g_direct_equal); + g_application_add_main_option( G_APPLICATION(app->application), "mobile", @@ -138,6 +140,8 @@ application_run(MESSENGER_Application *app) pthread_join(app->chat.tid, NULL); + g_hash_table_destroy(app->ui.bindings); + notify_uninit(); g_object_unref(app->application); @@ -147,7 +151,8 @@ typedef struct MESSENGER_ApplicationEventCall { MESSENGER_Application *app; MESSENGER_ApplicationEvent event; - void *cls; + int argc; + void **argv; } MESSENGER_ApplicationEventCall; static gboolean @@ -156,7 +161,10 @@ _application_event_call(gpointer user_data) MESSENGER_ApplicationEventCall *call; call = (MESSENGER_ApplicationEventCall*) user_data; - call->event(call->app, call->cls); + call->event(call->app, call->argc, call->argv); + + if (call->argc > 0) + GNUNET_free(call->argv); GNUNET_free(call); return FALSE; @@ -165,7 +173,8 @@ _application_event_call(gpointer user_data) void application_call_event(MESSENGER_Application *app, MESSENGER_ApplicationEvent event, - void *cls) + int argc, + void **argv) { MESSENGER_ApplicationEventCall *call; @@ -175,7 +184,17 @@ application_call_event(MESSENGER_Application *app, call->app = app; call->event = event; - call->cls = cls; + call->argc = argc; + call->argv = NULL; + + if (call->argc > 0) + { + call->argv = GNUNET_new_array(call->argc, void*); + + for (int i = 0; i < call->argc; i++) { + call->argv[i] = argv[i]; + } + } g_idle_add(_application_event_call, call); } diff --git a/src/application.h b/src/application.h @@ -61,6 +61,8 @@ typedef struct MESSENGER_Application int status; gboolean mobile; + GHashTable *bindings; + UI_MESSENGER_Handle messenger; UI_NEW_PLATFORM_Handle new_platform; @@ -76,12 +78,14 @@ void application_run(MESSENGER_Application *app); typedef void (*MESSENGER_ApplicationEvent) (MESSENGER_Application *app, - void *cls); + int argc, + void **argv); void application_call_event(MESSENGER_Application *app, MESSENGER_ApplicationEvent event, - void *cls); + int argc, + void **argv); void application_exit(MESSENGER_Application *app, diff --git a/src/chat/messenger.c b/src/chat/messenger.c @@ -52,7 +52,7 @@ _chat_messenger_idle(void *cls) static int _chat_messenger_message(void *cls, - UNUSED struct GNUNET_CHAT_Context *context, + struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) { MESSENGER_Application *app = (MESSENGER_Application*) cls; @@ -72,16 +72,23 @@ _chat_messenger_message(void *cls, switch (kind) { case GNUNET_CHAT_KIND_LOGIN: - application_call_event(app, event_update_profile, NULL); - break; - case GNUNET_CHAT_KIND_TEXT: - printf("text: %s\n", GNUNET_CHAT_message_get_text(message)); + { + application_call_event(app, event_update_profile, 0, NULL); break; + } case GNUNET_CHAT_KIND_JOIN: + { if (GNUNET_YES == GNUNET_CHAT_message_is_sent(message)) - application_call_event(app, event_update_chats, context); + application_call_event(app, event_update_chats, 1, (void**) &context); break; + } + case GNUNET_CHAT_KIND_TEXT: + { + void* event_data [2] = { context, &message }; + application_call_event(app, event_receive_message, 2, event_data); + break; + } default: break; } diff --git a/src/event.c b/src/event.c @@ -74,7 +74,8 @@ _clear_each_widget(GtkWidget *widget, void event_update_profile(MESSENGER_Application *app, - UNUSED void *cls) + UNUSED int argc, + UNUSED void **argv) { UI_MESSENGER_Handle *ui = &(app->ui.messenger); CHAT_MESSENGER_Handle *chat = &(app->chat.messenger); @@ -105,9 +106,13 @@ event_update_profile(MESSENGER_Application *app, void event_update_chats(MESSENGER_Application *app, - void *cls) + int argc, + void **argv) { - struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) cls; + if (argc < 1) + return; + + struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) argv[0]; if (GNUNET_CHAT_context_get_user_pointer(context)) return; @@ -120,4 +125,69 @@ event_update_chats(MESSENGER_Application *app, // TODO: put something better here to attach it! GNUNET_CHAT_context_set_user_pointer(context, ui); + + g_hash_table_insert( + app->ui.bindings, + app->ui.messenger.send_record_button, + context + ); + + g_hash_table_insert( + app->ui.bindings, + app->ui.messenger.send_text_view, + context + ); +} + +void +event_receive_message(MESSENGER_Application *app, + int argc, + void **argv) +{ + if (argc < 2) + return; + + struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) argv[0]; + + if (!GNUNET_CHAT_context_get_user_pointer(context)) + 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); + + if (GNUNET_YES != sent) + { + 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 : ""); + } + + struct GNUNET_TIME_Absolute timestamp = GNUNET_CHAT_message_get_timestamp( + msg + ); + + const char *text = GNUNET_CHAT_message_get_text(msg); + const char *time = GNUNET_STRINGS_absolute_time_to_string(timestamp); + + gtk_label_set_text(message->text_label, text? text : ""); + gtk_label_set_text(message->timestamp_label, time? time : ""); + + if (message->read_receipt_image) + // TODO: check read receipt + + gtk_container_add( + GTK_CONTAINER(app->ui.messenger.messages_listbox), + message->message_box + ); + + g_free(message); // TODO: this is just a test! } diff --git a/src/event.h b/src/event.h @@ -29,10 +29,17 @@ void event_update_profile(MESSENGER_Application *app, - void *cls); + int argc, + void **argv); void event_update_chats(MESSENGER_Application *app, - void *cls); + int argc, + void **argv); + +void +event_receive_message(MESSENGER_Application *app, + int argc, + void **argv); #endif /* EVENT_H_ */ diff --git a/src/ui/messenger.c b/src/ui/messenger.c @@ -24,6 +24,8 @@ #include "messenger.h" +#include <gtk-3.0/gdk/gdkkeys.h> + #include "message.h" #include "new_platform.h" #include "../application.h" @@ -125,7 +127,7 @@ handle_send_text_buffer_changed(GtkTextBuffer *buffer, } static void -handle_send_record_button_click(UNUSED GtkButton *button, +handle_send_record_button_click(GtkButton *button, gpointer user_data) { MESSENGER_Application *app = (MESSENGER_Application*) user_data; @@ -142,14 +144,12 @@ handle_send_record_button_click(UNUSED GtkButton *button, if (0 < g_utf8_strlen(text, 1)) { - // TODO: Actually send the message with current chat context! - - UI_MESSAGE_Handle *message = ui_message_new(app, TRUE); - - gtk_label_set_text(message->text_label, text); + struct GNUNET_CHAT_Context *context = g_hash_table_lookup( + app->ui.bindings, button + ); - gtk_container_add(GTK_CONTAINER(app->ui.messenger.messages_listbox), message->message_box); - g_free(message); // TODO: this is just a test! + if (context) + GNUNET_CHAT_context_send_text(context, text); } else { @@ -159,6 +159,40 @@ handle_send_record_button_click(UNUSED GtkButton *button, gtk_text_buffer_delete(buffer, &start, &end); } +static gboolean +handle_send_text_key_press (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + if ((event->state & GDK_SHIFT_MASK) || + ((event->keyval != GDK_KEY_Return) && + (event->keyval != GDK_KEY_KP_Enter))) + return FALSE; + + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (widget)); + + GtkTextIter start, end; + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_end_iter(buffer, &end); + + const gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); + + if (0 == g_utf8_strlen(text, 1)) + return FALSE; + + struct GNUNET_CHAT_Context *context = g_hash_table_lookup( + app->ui.bindings, widget + ); + + if (context) + GNUNET_CHAT_context_send_text(context, text); + + gtk_text_buffer_delete(buffer, &start, &end); + return TRUE; +} + static void handle_main_window_destroy(UNUSED GtkWidget *window, gpointer user_data) @@ -412,6 +446,13 @@ ui_messenger_init(MESSENGER_Application *app, app ); + g_signal_connect( + handle->send_text_view, + "key-press-event", + G_CALLBACK(handle_send_text_key_press), + app + ); + gtk_widget_show(GTK_WIDGET(handle->main_window)); g_signal_connect(