messenger-gtk

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

commit a05965ae509e3dd347d9643ccff99e9563f19365
parent ae8fc013b2f0879876cbe8f37634d6096d9053cd
Author: Jacki <jacki@thejackimonster.de>
Date:   Sun, 21 Apr 2024 04:42:02 +0200

Add button to select profile picture

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Mresources/ui/contact_info.ui | 28++++++++++++++++++++--------
Msrc/ui/contact_info.c | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/ui/contact_info.h | 1+
Msrc/ui/files.c | 22++++++++++++++++++++++
4 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/resources/ui/contact_info.ui b/resources/ui/contact_info.ui @@ -118,8 +118,6 @@ Author: Tobias Frisch <property name="visible">True</property> <property name="can-focus">False</property> <property name="halign">center</property> - <property name="margin-left">32</property> - <property name="margin-start">32</property> <property name="margin-top">8</property> <property name="margin-bottom">8</property> <property name="icon-name">avatar-default-symbolic</property> @@ -190,6 +188,17 @@ Author: Tobias Frisch </packing> </child> <child> + <object class="GtkFileChooserButton" id="profile_chooser_button"> + <property name="can-focus">False</property> + <property name="title" translatable="yes"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> <object class="GtkButton" id="reveal_identity_button"> <property name="visible">True</property> <property name="can-focus">True</property> @@ -231,7 +240,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">3</property> + <property name="position">4</property> </packing> </child> <child> @@ -275,7 +284,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">4</property> + <property name="position">5</property> </packing> </child> <child> @@ -319,7 +328,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">5</property> + <property name="position">6</property> </packing> </child> <child> @@ -419,7 +428,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">6</property> + <property name="position">7</property> </packing> </child> <child> @@ -464,7 +473,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">7</property> + <property name="position">8</property> </packing> </child> </object> @@ -589,7 +598,9 @@ Author: Tobias Frisch <property name="sort-indicator">True</property> <property name="sort-column-id">0</property> <child> - <object class="GtkCellRendererText"/> + <object class="GtkCellRendererText"> + <property name="ellipsize">end</property> + </object> <attributes> <attribute name="text">0</attribute> </attributes> @@ -605,6 +616,7 @@ Author: Tobias Frisch <child> <object class="GtkCellRendererText" id="value_renderer"> <property name="editable">True</property> + <property name="ellipsize">end</property> </object> <attributes> <attribute name="text">1</attribute> diff --git a/src/ui/contact_info.c b/src/ui/contact_info.c @@ -27,7 +27,9 @@ #include "chat_entry.h" #include "../application.h" +#include "../file.h" #include "../ui.h" + #include <gnunet/gnunet_chat_lib.h> #include <gnunet/gnunet_common.h> #include <gnunet/gnunet_time_lib.h> @@ -103,6 +105,104 @@ handle_contact_name_entry_activate(UNUSED GtkEntry *entry, } static void +handle_profile_chooser_update_preview(GtkFileChooser *file_chooser, + gpointer user_data) +{ + g_assert((file_chooser) && (user_data)); + + HdyAvatar *avatar = HDY_AVATAR(user_data); + + gboolean have_preview = false; + gchar *filename = gtk_file_chooser_get_preview_filename(file_chooser); + + if ((!filename) || (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))) + goto skip_preview; + + GFile *file = g_file_new_for_path(filename); + + if (!file) + goto skip_icon; + + GIcon *icon = g_file_icon_new(file); + + if (!icon) + goto skip_avatar; + + hdy_avatar_set_loadable_icon(avatar, G_LOADABLE_ICON(icon)); + have_preview = true; + +skip_avatar: + g_object_unref(file); + +skip_icon: + g_free(filename); + +skip_preview: + gtk_file_chooser_set_preview_widget_active(file_chooser, have_preview); +} + +static void +_cb_file_upload(void *cls, + const struct GNUNET_CHAT_File *file, + uint64_t completed, + uint64_t size) +{ + g_assert((cls) && (file)); + + MESSENGER_Application *app = (MESSENGER_Application*) cls; + + file_update_upload_info(file, completed, size); + + if (completed < size) + return; + + struct GNUNET_CHAT_Uri *uri = GNUNET_CHAT_file_get_uri(file); + + if (!uri) + return; + + char *uri_string = GNUNET_CHAT_uri_to_string(uri); + + if (uri_string) + { + GNUNET_CHAT_set_attribute( + app->chat.messenger.handle, + "profile", + uri_string, + GNUNET_TIME_relative_get_forever_() + ); + + GNUNET_free(uri_string); + } + + GNUNET_CHAT_uri_destroy(uri); +} + +static void +handle_profile_chooser_file_set(GtkFileChooserButton *button, + gpointer user_data) +{ + g_assert(user_data); + + GtkFileChooser *file_chooser = GTK_FILE_CHOOSER(button); + UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; + + gchar *filename = gtk_file_chooser_get_preview_filename(file_chooser); + + if (!filename) + return; + + GNUNET_CHAT_upload_file( + handle->app->chat.messenger.handle, + filename, + _cb_file_upload, + handle->app + ); + + g_free(filename); +} + +static void _contact_info_switch_stack_to(UI_CONTACT_INFO_Handle *handle, GtkWidget *page_widget) { @@ -751,6 +851,24 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, handle ); + handle->profile_chooser_button = GTK_FILE_CHOOSER_BUTTON( + gtk_builder_get_object(handle->builder, "profile_chooser_button") + ); + + g_signal_connect( + handle->profile_chooser_button, + "update-preview", + G_CALLBACK(handle_profile_chooser_update_preview), + handle->contact_avatar + ); + + g_signal_connect( + handle->profile_chooser_button, + "file-set", + G_CALLBACK(handle_profile_chooser_file_set), + handle + ); + handle->reveal_identity_button = GTK_BUTTON( gtk_builder_get_object(handle->builder, "reveal_identity_button") ); @@ -1049,6 +1167,11 @@ ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, ui_entry_set_text(handle->id_entry, key); gtk_widget_set_sensitive( + GTK_WIDGET(handle->profile_chooser_button), + editable + ); + + gtk_widget_set_sensitive( GTK_WIDGET(handle->reveal_identity_button), key? TRUE : FALSE ); @@ -1069,6 +1192,11 @@ ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, ); gtk_widget_set_visible( + GTK_WIDGET(handle->profile_chooser_button), + editable + ); + + gtk_widget_set_visible( GTK_WIDGET(handle->share_attributes_button), !editable ); diff --git a/src/ui/contact_info.h b/src/ui/contact_info.h @@ -47,6 +47,7 @@ typedef struct UI_CONTACT_INFO_Handle GtkButton *contact_edit_button; GtkImage *contact_edit_symbol; + GtkFileChooserButton *profile_chooser_button; GtkButton *reveal_identity_button; GtkButton *list_attributes_button; GtkButton *share_attributes_button; diff --git a/src/ui/files.c b/src/ui/files.c @@ -27,6 +27,7 @@ #include "file_entry.h" #include "../application.h" #include "../ui.h" +#include <gnunet/gnunet_chat_lib.h> #include <gnunet/gnunet_common.h> static void @@ -65,6 +66,27 @@ handle_files_listbox_row_activated(UNUSED GtkListBox* listbox, UI_FILES_Handle *handle = &(app->ui.files); + struct GNUNET_CHAT_File *file = (struct GNUNET_CHAT_File*) ( + g_object_get_qdata(G_OBJECT(row), app->quarks.data) + ); + + const gdouble progress = ( + (gdouble) GNUNET_CHAT_file_get_local_size(file) / + GNUNET_CHAT_file_get_size(file) + ); + + gtk_progress_bar_set_fraction(handle->storage_progress_bar, progress); + + if (GNUNET_YES == GNUNET_CHAT_file_is_downloading(file)) + gtk_stack_set_visible_child(handle->play_icon_stack, handle->pause_icon_image); + else + gtk_stack_set_visible_child(handle->play_icon_stack, handle->play_icon_image); + + gtk_widget_set_visible( + GTK_WIDGET(handle->play_pause_button), + GNUNET_YES != GNUNET_CHAT_file_is_ready(file) + ); + UI_FILE_ENTRY_Handle *entry = (UI_FILE_ENTRY_Handle*) ( g_object_get_qdata(G_OBJECT(row), app->quarks.ui) );