messenger-gtk

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

commit d3c77142308567e16af38beb704c3436464c0cff
parent aefac32b50c41a2a6f137b84b80753cd26333aa5
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Mon,  5 Dec 2022 22:20:29 +0100

Support ogg playback via internal media player

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

Diffstat:
Mresources/ui/message_content.ui | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/ui/message.c | 137++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/ui/message.h | 7++++++-
3 files changed, 230 insertions(+), 20 deletions(-)

diff --git a/resources/ui/message_content.ui b/resources/ui/message_content.ui @@ -219,6 +219,112 @@ Author: Tobias Frisch <property name="position">3</property> </packing> </child> + <child> + <object class="GtkRevealer" id="media_revealer"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="transition-type">none</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">4</property> + <child> + <object class="GtkImage" id="media_type_image"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="xpad">24</property> + <property name="ypad">24</property> + <property name="icon-name">video-x-generic-symbolic</property> + <property name="icon_size">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="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel" id="media_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="xalign">0</property> + <property name="yalign">1</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkProgressBar" id="media_progress_bar"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </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">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="media_button"> + <property name="visible">True</property> + <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">media-playback-start-symbolic</property> + </object> + </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">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="name">page0</property> + <property name="title" translatable="yes">page0</property> + <property name="position">4</property> + </packing> + </child> </object> <packing> <property name="expand">True</property> diff --git a/src/ui/message.c b/src/ui/message.c @@ -101,25 +101,53 @@ handle_file_button_click(GtkButton *button, GString* uri = g_string_new("file://"); g_string_append(uri, preview); - if (handle->media) - { - ui_play_media_window_init(app, &(app->ui.play_media)); - - ui_play_media_window_update( - &(app->ui.play_media), - uri->str, - file - ); - - gtk_widget_show(GTK_WIDGET(app->ui.play_media.window)); - } - else if (!g_app_info_launch_default_for_uri(uri->str, NULL, NULL)) + if (!g_app_info_launch_default_for_uri(uri->str, NULL, NULL)) GNUNET_CHAT_file_close_preview(file); g_string_free(uri, TRUE); } } +static void +handle_media_button_click(GtkButton *button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + UI_MESSAGE_Handle* handle = (UI_MESSAGE_Handle*) ( + g_object_get_qdata(G_OBJECT(button), app->quarks.ui) + ); + + if (!handle) + return; + + struct GNUNET_CHAT_File *file = (struct GNUNET_CHAT_File*) ( + g_object_get_qdata(G_OBJECT(handle->media_progress_bar), app->quarks.data) + ); + + if (!file) + return; + + const gchar *preview = GNUNET_CHAT_file_open_preview(file); + + if (!preview) + return; + + ui_play_media_window_init(app, &(app->ui.play_media)); + + GString* uri = g_string_new("file://"); + g_string_append(uri, preview); + + ui_play_media_window_update( + &(app->ui.play_media), + uri->str, + file + ); + + gtk_widget_show(GTK_WIDGET(app->ui.play_media.window)); + g_string_free(uri, TRUE); +} + static int handle_message_redraw_animation(gpointer user_data) { @@ -260,7 +288,6 @@ ui_message_new(MESSENGER_Application *app, UI_MESSAGE_Handle* handle = g_malloc(sizeof(UI_MESSAGE_Handle)); handle->type = type; - handle->media = FALSE; handle->timestamp = GNUNET_TIME_absolute_get_zero_(); handle->msg = NULL; @@ -391,6 +418,35 @@ ui_message_new(MESSENGER_Application *app, gtk_builder_get_object(handle->builder[1], "whisper_box") ); + handle->media_revealer = GTK_REVEALER( + gtk_builder_get_object(handle->builder[1], "media_revealer") + ); + + handle->media_type_image = GTK_IMAGE( + gtk_builder_get_object(handle->builder[1], "media_type_image") + ); + + handle->media_label = GTK_LABEL( + gtk_builder_get_object(handle->builder[1], "media_label") + ); + + handle->media_progress_bar = GTK_PROGRESS_BAR( + gtk_builder_get_object(handle->builder[1], "media_progress_bar") + ); + + handle->media_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder[1], "media_button") + ); + + g_signal_connect( + handle->media_button, + "clicked", + G_CALLBACK(handle_media_button_click), + app + ); + + g_object_set_qdata(G_OBJECT(handle->media_button), app->quarks.ui, handle); + switch (handle->type) { case UI_MESSAGE_STATUS: @@ -443,6 +499,23 @@ ui_message_refresh(UI_MESSAGE_Handle *handle) gtk_widget_hide(GTK_WIDGET(handle->read_receipt_image)); } +gboolean +_message_media_supports_file_extension(const gchar *filename) +{ + if (!filename) + return FALSE; + + const char* extension = strrchr(filename, '.'); + + if (!extension) + return FALSE; + + if (0 == g_strcmp0(extension, ".ogg")) + return TRUE; + + return FALSE; +} + static void _update_file_message(UI_MESSAGE_Handle *handle, MESSENGER_Application *app, @@ -502,20 +575,46 @@ _update_file_message(UI_MESSAGE_Handle *handle, return; } - if (ui_play_media_window_supports_file_extension(filename)) + GNUNET_CHAT_file_close_preview(file); + + if (_message_media_supports_file_extension(filename)) { - handle->media = TRUE; - goto file_progress; + gtk_image_set_from_icon_name( + handle->media_type_image, + "audio-x-generic-symbolic", + GTK_ICON_SIZE_DND + ); + + goto media_content; } - GNUNET_CHAT_file_close_preview(file); + if (!ui_play_media_window_supports_file_extension(filename)) + goto file_progress; + +media_content: + ui_label_set_text(handle->media_label, filename); + + gtk_stack_set_visible_child( + handle->content_stack, + GTK_WIDGET(handle->media_revealer) + ); + + gtk_revealer_set_reveal_child(handle->media_revealer, TRUE); + + g_object_set_qdata( + G_OBJECT(handle->media_progress_bar), + app->quarks.data, + file + ); + + return; file_progress: gtk_progress_bar_set_fraction(handle->file_progress_bar, 1.0); gtk_image_set_from_icon_name( handle->file_status_image, - (handle->media? "video-x-generic-symbolic" : "document-open-symbolic"), + "document-open-symbolic", GTK_ICON_SIZE_BUTTON ); diff --git a/src/ui/message.h b/src/ui/message.h @@ -44,7 +44,6 @@ typedef enum UI_MESSAGE_Type typedef struct UI_MESSAGE_Handle { UI_MESSAGE_Type type; - gboolean media; struct GNUNET_TIME_Absolute timestamp; const struct GNUNET_CHAT_Message *msg; @@ -78,6 +77,12 @@ typedef struct UI_MESSAGE_Handle GtkWidget *whisper_box; + GtkRevealer *media_revealer; + GtkImage *media_type_image; + GtkLabel *media_label; + GtkProgressBar *media_progress_bar; + GtkButton *media_button; + GdkPixbuf *preview_image; GdkPixbufAnimation *preview_animation; GdkPixbufAnimationIter *preview_animation_iter;