aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-01-10 17:21:28 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2022-01-10 17:21:28 +0100
commit69e3d367f8e0d1168d5c6d6daebed1d2722b265c (patch)
tree369ff4e9421743fe513d0159d878736fdbf3c2c0
parent031a28213115d042de65ce344a8f4a23a8ba056a (diff)
downloadmessenger-gtk-69e3d367f8e0d1168d5c6d6daebed1d2722b265c.tar.gz
messenger-gtk-69e3d367f8e0d1168d5c6d6daebed1d2722b265c.zip
Adding visual list of current uploading files to be sent
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--Makefile2
-rw-r--r--resources/ui.gresource.xml3
-rw-r--r--resources/ui/chat.ui39
-rw-r--r--resources/ui/file_load_entry.ui117
-rw-r--r--src/contact.c4
-rw-r--r--src/event.c23
-rw-r--r--src/file.c74
-rw-r--r--src/file.h51
-rw-r--r--src/ui/chat.c131
-rw-r--r--src/ui/chat.h28
-rw-r--r--src/ui/chat_entry.c6
-rw-r--r--src/ui/file_load_entry.c90
-rw-r--r--src/ui/file_load_entry.h56
-rw-r--r--src/ui/new_contact.c2
-rw-r--r--src/ui/send_file.c52
15 files changed, 635 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index ee9c5a9..3c0cfc7 100644
--- a/Makefile
+++ b/Makefile
@@ -10,12 +10,14 @@ SOURCES = messenger_gtk.c\
10 application.c\ 10 application.c\
11 contact.c\ 11 contact.c\
12 event.c\ 12 event.c\
13 file.c\
13 resources.c\ 14 resources.c\
14 chat/messenger.c\ 15 chat/messenger.c\
15 ui/chat.c\ 16 ui/chat.c\
16 ui/chat_entry.c\ 17 ui/chat_entry.c\
17 ui/contact_entry.c\ 18 ui/contact_entry.c\
18 ui/contacts.c\ 19 ui/contacts.c\
20 ui/file_load_entry.c\
19 ui/invite_contact.c\ 21 ui/invite_contact.c\
20 ui/message.c\ 22 ui/message.c\
21 ui/messenger.c\ 23 ui/messenger.c\
diff --git a/resources/ui.gresource.xml b/resources/ui.gresource.xml
index dfa2e9d..122697e 100644
--- a/resources/ui.gresource.xml
+++ b/resources/ui.gresource.xml
@@ -4,6 +4,7 @@
4 <file compressed="true">ui/chat_entry.ui</file> 4 <file compressed="true">ui/chat_entry.ui</file>
5 <file compressed="true">ui/chat.ui</file> 5 <file compressed="true">ui/chat.ui</file>
6 <file compressed="true">ui/contacts.ui</file> 6 <file compressed="true">ui/contacts.ui</file>
7 <file compressed="true">ui/file_load_entry.ui</file>
7 <file compressed="true">ui/invite_contact.ui</file> 8 <file compressed="true">ui/invite_contact.ui</file>
8 <file compressed="true">ui/message_content.ui</file> 9 <file compressed="true">ui/message_content.ui</file>
9 <file compressed="true">ui/message.ui</file> 10 <file compressed="true">ui/message.ui</file>
@@ -19,4 +20,4 @@
19 <file compressed="true">ui/send_file.ui</file> 20 <file compressed="true">ui/send_file.ui</file>
20 <file compressed="true">ui/settings.ui</file> 21 <file compressed="true">ui/settings.ui</file>
21 </gresource> 22 </gresource>
22</gresources> \ No newline at end of file 23</gresources>
diff --git a/resources/ui/chat.ui b/resources/ui/chat.ui
index c70eb40..d928dff 100644
--- a/resources/ui/chat.ui
+++ b/resources/ui/chat.ui
@@ -69,7 +69,6 @@ Author: Tobias Frisch
69 <object class="GtkBox"> 69 <object class="GtkBox">
70 <property name="visible">True</property> 70 <property name="visible">True</property>
71 <property name="can-focus">False</property> 71 <property name="can-focus">False</property>
72 <property name="halign">start</property>
73 <property name="margin-start">4</property> 72 <property name="margin-start">4</property>
74 <property name="margin-end">4</property> 73 <property name="margin-end">4</property>
75 <property name="orientation">vertical</property> 74 <property name="orientation">vertical</property>
@@ -77,6 +76,8 @@ Author: Tobias Frisch
77 <object class="GtkLabel" id="chat_title"> 76 <object class="GtkLabel" id="chat_title">
78 <property name="visible">True</property> 77 <property name="visible">True</property>
79 <property name="can-focus">False</property> 78 <property name="can-focus">False</property>
79 <property name="ellipsize">end</property>
80 <property name="single-line-mode">True</property>
80 <property name="xalign">0</property> 81 <property name="xalign">0</property>
81 <attributes> 82 <attributes>
82 <attribute name="weight" value="bold"/> 83 <attribute name="weight" value="bold"/>
@@ -92,6 +93,8 @@ Author: Tobias Frisch
92 <object class="GtkLabel" id="chat_subtitle"> 93 <object class="GtkLabel" id="chat_subtitle">
93 <property name="visible">True</property> 94 <property name="visible">True</property>
94 <property name="can-focus">False</property> 95 <property name="can-focus">False</property>
96 <property name="ellipsize">end</property>
97 <property name="single-line-mode">True</property>
95 <property name="xalign">0</property> 98 <property name="xalign">0</property>
96 <attributes> 99 <attributes>
97 <attribute name="weight" value="light"/> 100 <attribute name="weight" value="light"/>
@@ -101,7 +104,7 @@ Author: Tobias Frisch
101 </style> 104 </style>
102 </object> 105 </object>
103 <packing> 106 <packing>
104 <property name="expand">True</property> 107 <property name="expand">False</property>
105 <property name="fill">True</property> 108 <property name="fill">True</property>
106 <property name="position">1</property> 109 <property name="position">1</property>
107 </packing> 110 </packing>
@@ -134,6 +137,26 @@ Author: Tobias Frisch
134 <property name="position">1</property> 137 <property name="position">1</property>
135 </packing> 138 </packing>
136 </child> 139 </child>
140 <child>
141 <object class="GtkButton" id="chat_load_button">
142 <property name="can-focus">True</property>
143 <property name="receives-default">True</property>
144 <property name="relief">none</property>
145 <child>
146 <object class="GtkSpinner">
147 <property name="visible">True</property>
148 <property name="can-focus">False</property>
149 <property name="active">True</property>
150 </object>
151 </child>
152 </object>
153 <packing>
154 <property name="expand">False</property>
155 <property name="fill">True</property>
156 <property name="pack-type">end</property>
157 <property name="position">3</property>
158 </packing>
159 </child>
137 <style> 160 <style>
138 <class name=".header-box"/> 161 <class name=".header-box"/>
139 </style> 162 </style>
@@ -530,4 +553,16 @@ Author: Tobias Frisch
530 </packing> 553 </packing>
531 </child> 554 </child>
532 </object> 555 </object>
556 <object class="GtkPopover" id="chat_load_popover">
557 <property name="can-focus">False</property>
558 <property name="relative-to">chat_load_button</property>
559 <property name="position">bottom</property>
560 <child>
561 <object class="GtkListBox" id="chat_load_listbox">
562 <property name="visible">True</property>
563 <property name="can-focus">False</property>
564 <property name="selection-mode">none</property>
565 </object>
566 </child>
567 </object>
533</interface> 568</interface>
diff --git a/resources/ui/file_load_entry.ui b/resources/ui/file_load_entry.ui
new file mode 100644
index 0000000..0e0a8ac
--- /dev/null
+++ b/resources/ui/file_load_entry.ui
@@ -0,0 +1,117 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!-- Generated with glade 3.38.2
3
4Copyright (C) 2022 GNUnet e.V.
5
6GNUnet is free software: you can redistribute it and/or modify it
7under the terms of the GNU Affero General Public License as published
8by the Free Software Foundation, either version 3 of the License,
9or (at your option) any later version.
10
11GNUnet is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14Affero General Public License for more details.
15
16You should have received a copy of the GNU Affero General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19SPDX-License-Identifier: AGPL3.0-or-later
20Author: Tobias Frisch
21
22-->
23<interface>
24 <requires lib="gtk+" version="3.24"/>
25 <object class="GtkBox" id="entry_box">
26 <property name="visible">True</property>
27 <property name="can-focus">False</property>
28 <property name="border-width">4</property>
29 <property name="spacing">8</property>
30 <child>
31 <object class="GtkBox">
32 <property name="visible">True</property>
33 <property name="can-focus">False</property>
34 <property name="border-width">8</property>
35 <property name="orientation">vertical</property>
36 <child>
37 <object class="GtkImage" id="file_image">
38 <property name="visible">True</property>
39 <property name="can-focus">False</property>
40 <property name="icon-name">folder-documents-symbolic</property>
41 <property name="icon_size">3</property>
42 </object>
43 <packing>
44 <property name="expand">True</property>
45 <property name="fill">True</property>
46 <property name="position">0</property>
47 </packing>
48 </child>
49 </object>
50 <packing>
51 <property name="expand">False</property>
52 <property name="fill">True</property>
53 <property name="position">0</property>
54 </packing>
55 </child>
56 <child>
57 <object class="GtkBox">
58 <property name="visible">True</property>
59 <property name="can-focus">False</property>
60 <property name="orientation">vertical</property>
61 <child>
62 <object class="GtkLabel" id="file_label">
63 <property name="visible">True</property>
64 <property name="can-focus">False</property>
65 <property name="ellipsize">start</property>
66 <property name="single-line-mode">True</property>
67 <property name="xalign">0</property>
68 <property name="yalign">1</property>
69 </object>
70 <packing>
71 <property name="expand">True</property>
72 <property name="fill">True</property>
73 <property name="position">0</property>
74 </packing>
75 </child>
76 <child>
77 <object class="GtkProgressBar" id="load_progress_bar">
78 <property name="height-request">8</property>
79 <property name="visible">True</property>
80 <property name="can-focus">False</property>
81 </object>
82 <packing>
83 <property name="expand">False</property>
84 <property name="fill">True</property>
85 <property name="position">1</property>
86 </packing>
87 </child>
88 </object>
89 <packing>
90 <property name="expand">True</property>
91 <property name="fill">True</property>
92 <property name="position">1</property>
93 </packing>
94 </child>
95 <child>
96 <object class="GtkButton" id="cancel_button">
97 <property name="can-focus">True</property>
98 <property name="receives-default">True</property>
99 <property name="valign">center</property>
100 <property name="relief">none</property>
101 <child>
102 <object class="GtkImage">
103 <property name="visible">True</property>
104 <property name="can-focus">False</property>
105 <property name="icon-name">process-stop-symbolic</property>
106 </object>
107 </child>
108 </object>
109 <packing>
110 <property name="expand">False</property>
111 <property name="fill">True</property>
112 <property name="pack-type">end</property>
113 <property name="position">2</property>
114 </packing>
115 </child>
116 </object>
117</interface>
diff --git a/src/contact.c b/src/contact.c
index e87e87b..78045bb 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V. 3 Copyright (C) 2021--2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -27,7 +27,7 @@
27void 27void
28contact_create_info(struct GNUNET_CHAT_Contact *contact) 28contact_create_info(struct GNUNET_CHAT_Contact *contact)
29{ 29{
30 if (GNUNET_CHAT_contact_get_user_pointer(contact)) 30 if ((!contact) || (GNUNET_CHAT_contact_get_user_pointer(contact)))
31 return; 31 return;
32 32
33 MESSENGER_ContactInfo* info = g_malloc(sizeof(MESSENGER_ContactInfo)); 33 MESSENGER_ContactInfo* info = g_malloc(sizeof(MESSENGER_ContactInfo));
diff --git a/src/event.c b/src/event.c
index 8f913f2..e1e2601 100644
--- a/src/event.c
+++ b/src/event.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V. 3 Copyright (C) 2021--2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -268,12 +268,7 @@ event_joining_contact(MESSENGER_Application *app,
268 gtk_label_set_text(message->text_label, join_message); 268 gtk_label_set_text(message->text_label, join_message);
269 gtk_label_set_text(message->timestamp_label, time? time : ""); 269 gtk_label_set_text(message->timestamp_label, time? time : "");
270 270
271 gtk_container_add( 271 ui_chat_add_message(handle->chat, message);
272 GTK_CONTAINER(handle->chat->messages_listbox),
273 message->message_box
274 );
275
276 handle->chat->messages = g_list_prepend(handle->chat->messages, message);
277 ui_chat_entry_update(handle, app, context); 272 ui_chat_entry_update(handle, app, context);
278} 273}
279 274
@@ -357,12 +352,7 @@ event_invitation(UNUSED MESSENGER_Application *app,
357 gtk_widget_show(GTK_WIDGET(message->deny_button)); 352 gtk_widget_show(GTK_WIDGET(message->deny_button));
358 gtk_widget_show(GTK_WIDGET(message->accept_button)); 353 gtk_widget_show(GTK_WIDGET(message->accept_button));
359 354
360 gtk_container_add( 355 ui_chat_add_message(handle->chat, message);
361 GTK_CONTAINER(handle->chat->messages_listbox),
362 message->message_box
363 );
364
365 handle->chat->messages = g_list_prepend(handle->chat->messages, message);
366 ui_chat_entry_update(handle, app, context); 356 ui_chat_entry_update(handle, app, context);
367} 357}
368 358
@@ -412,11 +402,6 @@ event_receive_message(UNUSED MESSENGER_Application *app,
412 gtk_label_set_text(message->text_label, text? text : ""); 402 gtk_label_set_text(message->text_label, text? text : "");
413 gtk_label_set_text(message->timestamp_label, time? time : ""); 403 gtk_label_set_text(message->timestamp_label, time? time : "");
414 404
415 gtk_container_add( 405 ui_chat_add_message(handle->chat, message);
416 GTK_CONTAINER(handle->chat->messages_listbox),
417 message->message_box
418 );
419
420 handle->chat->messages = g_list_prepend(handle->chat->messages, message);
421 ui_chat_entry_update(handle, app, context); 406 ui_chat_entry_update(handle, app, context);
422} 407}
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 0000000..4b36f91
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,74 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file file.c
23 */
24
25#include "file.h"
26
27void
28file_create_info(struct GNUNET_CHAT_File *file)
29{
30 if ((!file) || (GNUNET_CHAT_file_get_user_pointer(file)))
31 return;
32
33 MESSENGER_FileInfo* info = g_malloc(sizeof(MESSENGER_FileInfo));
34
35 info->file_messages = NULL;
36
37 GNUNET_CHAT_file_set_user_pointer(file, info);
38}
39
40void
41file_destroy_info(struct GNUNET_CHAT_File *file)
42{
43 MESSENGER_FileInfo* info = GNUNET_CHAT_file_get_user_pointer(file);
44
45 if (!info)
46 return;
47
48 if (info->file_messages)
49 g_list_free(info->file_messages);
50
51 g_free(info);
52
53 GNUNET_CHAT_file_set_user_pointer(file, NULL);
54}
55
56void
57file_add_ui_message_to_info(const struct GNUNET_CHAT_File *file,
58 UI_MESSAGE_Handle *message)
59{
60 MESSENGER_FileInfo* info = GNUNET_CHAT_file_get_user_pointer(file);
61
62 if ((!info) || (!message))
63 return;
64
65 info->file_messages = g_list_append(info->file_messages, message);
66}
67
68void
69file_update_upload_info(const struct GNUNET_CHAT_File *file,
70 uint64_t completed,
71 uint64_t size)
72{
73 //
74}
diff --git a/src/file.h b/src/file.h
new file mode 100644
index 0000000..dc8e585
--- /dev/null
+++ b/src/file.h
@@ -0,0 +1,51 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file file.h
23 */
24
25#ifndef FILE_H_
26#define FILE_H_
27
28#include "application.h"
29#include "ui/message.h"
30
31typedef struct MESSENGER_FileInfo
32{
33 GList *file_messages;
34} MESSENGER_FileInfo;
35
36void
37file_create_info(struct GNUNET_CHAT_File *file);
38
39void
40file_destroy_info(struct GNUNET_CHAT_File *file);
41
42void
43file_add_ui_message_to_info(const struct GNUNET_CHAT_File *file,
44 UI_MESSAGE_Handle *message);
45
46void
47file_update_upload_info(const struct GNUNET_CHAT_File *file,
48 uint64_t completed,
49 uint64_t size);
50
51#endif /* FILE_H_ */
diff --git a/src/ui/chat.c b/src/ui/chat.c
index 71f7ebc..0039a5d 100644
--- a/src/ui/chat.c
+++ b/src/ui/chat.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V. 3 Copyright (C) 2021--2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -26,6 +26,7 @@
26 26
27#include <gdk/gdkkeysyms.h> 27#include <gdk/gdkkeysyms.h>
28 28
29#include "file_load_entry.h"
29#include "message.h" 30#include "message.h"
30#include "messenger.h" 31#include "messenger.h"
31#include "picker.h" 32#include "picker.h"
@@ -40,11 +41,22 @@ handle_flap_via_button_click(UNUSED GtkButton *button,
40{ 41{
41 HdyFlap *flap = HDY_FLAP(user_data); 42 HdyFlap *flap = HDY_FLAP(user_data);
42 43
43 if (TRUE == hdy_flap_get_reveal_flap(flap)) { 44 if (TRUE == hdy_flap_get_reveal_flap(flap))
44 hdy_flap_set_reveal_flap(flap, FALSE); 45 hdy_flap_set_reveal_flap(flap, FALSE);
45 } else { 46 else
46 hdy_flap_set_reveal_flap(flap, TRUE); 47 hdy_flap_set_reveal_flap(flap, TRUE);
47 } 48}
49
50static void
51handle_popover_via_button_click(UNUSED GtkButton *button,
52 gpointer user_data)
53{
54 GtkPopover *popover = GTK_POPOVER(user_data);
55
56 if (gtk_widget_is_visible(GTK_WIDGET(popover)))
57 gtk_popover_popdown(popover);
58 else
59 gtk_popover_popup(popover);
48} 60}
49 61
50static void 62static void
@@ -273,12 +285,16 @@ handle_picker_button_click(UNUSED GtkButton *button,
273UI_CHAT_Handle* 285UI_CHAT_Handle*
274ui_chat_new(MESSENGER_Application *app) 286ui_chat_new(MESSENGER_Application *app)
275{ 287{
288 GNUNET_assert(app);
289
276 UI_CHAT_Handle *handle = g_malloc(sizeof(UI_CHAT_Handle)); 290 UI_CHAT_Handle *handle = g_malloc(sizeof(UI_CHAT_Handle));
277 UI_MESSENGER_Handle *messenger = &(app->ui.messenger); 291 UI_MESSENGER_Handle *messenger = &(app->ui.messenger);
278 292
279 handle->messages = NULL; 293 handle->messages = NULL;
280 handle->edge_value = 0; 294 handle->edge_value = 0;
281 295
296 handle->loads = NULL;
297
282 handle->builder = gtk_builder_new_from_resource( 298 handle->builder = gtk_builder_new_from_resource(
283 application_get_resource_path(app, "ui/chat.ui") 299 application_get_resource_path(app, "ui/chat.ui")
284 ); 300 );
@@ -318,6 +334,25 @@ ui_chat_new(MESSENGER_Application *app)
318 gtk_builder_get_object(handle->builder, "chat_subtitle") 334 gtk_builder_get_object(handle->builder, "chat_subtitle")
319 ); 335 );
320 336
337 handle->chat_load_button = GTK_BUTTON(
338 gtk_builder_get_object(handle->builder, "chat_load_button")
339 );
340
341 handle->chat_load_popover = GTK_POPOVER(
342 gtk_builder_get_object(handle->builder, "chat_load_popover")
343 );
344
345 handle->chat_load_listbox = GTK_LIST_BOX(
346 gtk_builder_get_object(handle->builder, "chat_load_listbox")
347 );
348
349 g_signal_connect(
350 handle->chat_load_button,
351 "clicked",
352 G_CALLBACK(handle_popover_via_button_click),
353 handle->chat_load_popover
354 );
355
321 handle->chat_details_button = GTK_BUTTON( 356 handle->chat_details_button = GTK_BUTTON(
322 gtk_builder_get_object(handle->builder, "chat_details_button") 357 gtk_builder_get_object(handle->builder, "chat_details_button")
323 ); 358 );
@@ -505,6 +540,8 @@ ui_chat_update(UI_CHAT_Handle *handle,
505 MESSENGER_Application *app, 540 MESSENGER_Application *app,
506 const struct GNUNET_CHAT_Context* context) 541 const struct GNUNET_CHAT_Context* context)
507{ 542{
543 GNUNET_assert((handle) && (app) && (context));
544
508 const struct GNUNET_CHAT_Contact* contact; 545 const struct GNUNET_CHAT_Contact* contact;
509 const struct GNUNET_CHAT_Group* group; 546 const struct GNUNET_CHAT_Group* group;
510 547
@@ -586,7 +623,7 @@ ui_chat_update(UI_CHAT_Handle *handle,
586 gtk_widget_set_sensitive(GTK_WIDGET(handle->emoji_button), activated); 623 gtk_widget_set_sensitive(GTK_WIDGET(handle->emoji_button), activated);
587 gtk_widget_set_sensitive(GTK_WIDGET(handle->send_record_button), activated); 624 gtk_widget_set_sensitive(GTK_WIDGET(handle->send_record_button), activated);
588 625
589 if (!handle->messages) 626 if (!(handle->messages))
590 return; 627 return;
591 628
592 UI_MESSAGE_Handle *message = ( 629 UI_MESSAGE_Handle *message = (
@@ -602,6 +639,8 @@ ui_chat_update(UI_CHAT_Handle *handle,
602void 639void
603ui_chat_delete(UI_CHAT_Handle *handle) 640ui_chat_delete(UI_CHAT_Handle *handle)
604{ 641{
642 GNUNET_assert(handle);
643
605 ui_picker_delete(handle->picker); 644 ui_picker_delete(handle->picker);
606 645
607 g_object_unref(handle->builder); 646 g_object_unref(handle->builder);
@@ -615,8 +654,90 @@ ui_chat_delete(UI_CHAT_Handle *handle)
615 list = list->next; 654 list = list->next;
616 } 655 }
617 656
657 list = handle->loads;
658
659 while (list) {
660 if (list->data)
661 ui_file_load_entry_delete((UI_FILE_LOAD_ENTRY_Handle*) list->data);
662
663 list = list->next;
664 }
665
618 if (handle->messages) 666 if (handle->messages)
619 g_list_free(handle->messages); 667 g_list_free(handle->messages);
620 668
669 if (handle->loads)
670 g_list_free(handle->loads);
671
621 g_free(handle); 672 g_free(handle);
622} 673}
674
675void
676ui_chat_add_message(UI_CHAT_Handle *handle,
677 UI_MESSAGE_Handle *message)
678{
679 GNUNET_assert((handle) && (message));
680
681 gtk_container_add(
682 GTK_CONTAINER(handle->messages_listbox),
683 message->message_box
684 );
685
686 handle->messages = g_list_prepend(handle->messages, message);
687}
688
689void
690ui_chat_remove_message(UI_CHAT_Handle *handle,
691 UI_MESSAGE_Handle *message)
692{
693 GNUNET_assert((handle) && (message));
694
695 handle->messages = g_list_remove(handle->messages, message);
696
697 gtk_container_remove(
698 GTK_CONTAINER(handle->messages_listbox),
699 gtk_widget_get_parent(GTK_WIDGET(message->message_box))
700 );
701}
702
703void
704ui_chat_add_file_load(UI_CHAT_Handle *handle,
705 UI_FILE_LOAD_ENTRY_Handle *file_load)
706{
707 GNUNET_assert((handle) && (file_load));
708
709 gtk_container_add(
710 GTK_CONTAINER(handle->chat_load_listbox),
711 file_load->entry_box
712 );
713
714 handle->loads = g_list_append(handle->loads, file_load);
715
716 gtk_widget_show(GTK_WIDGET(handle->chat_load_button));
717
718 file_load->chat = handle;
719}
720
721void
722ui_chat_remove_file_load(UI_CHAT_Handle *handle,
723 UI_FILE_LOAD_ENTRY_Handle *file_load)
724{
725 GNUNET_assert((handle) && (file_load) && (handle == file_load->chat));
726
727 handle->loads = g_list_remove(handle->loads, file_load);
728
729 gtk_container_remove(
730 GTK_CONTAINER(handle->chat_load_listbox),
731 gtk_widget_get_parent(GTK_WIDGET(file_load->entry_box))
732 );
733
734 if (handle->loads)
735 return;
736
737 if (gtk_widget_is_visible(GTK_WIDGET(handle->chat_load_popover)))
738 gtk_popover_popdown(handle->chat_load_popover);
739
740 gtk_widget_hide(GTK_WIDGET(handle->chat_load_button));
741
742 file_load->chat = NULL;
743}
diff --git a/src/ui/chat.h b/src/ui/chat.h
index 6619506..6ce6064 100644
--- a/src/ui/chat.h
+++ b/src/ui/chat.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V. 3 Copyright (C) 2021--2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -32,13 +32,17 @@
32#include <gnunet/gnunet_chat_lib.h> 32#include <gnunet/gnunet_chat_lib.h>
33 33
34typedef struct MESSENGER_Application MESSENGER_Application; 34typedef struct MESSENGER_Application MESSENGER_Application;
35typedef struct UI_MESSAGE_Handle UI_MESSAGE_Handle;
35typedef struct UI_PICKER_Handle UI_PICKER_Handle; 36typedef struct UI_PICKER_Handle UI_PICKER_Handle;
37typedef struct UI_FILE_LOAD_ENTRY_Handle UI_FILE_LOAD_ENTRY_Handle;
36 38
37typedef struct UI_CHAT_Handle 39typedef struct UI_CHAT_Handle
38{ 40{
39 GList *messages; 41 GList *messages;
40 gdouble edge_value; 42 gdouble edge_value;
41 43
44 GList *loads;
45
42 GtkBuilder *builder; 46 GtkBuilder *builder;
43 GtkWidget *chat_box; 47 GtkWidget *chat_box;
44 48
@@ -48,8 +52,12 @@ typedef struct UI_CHAT_Handle
48 52
49 GtkLabel *chat_title; 53 GtkLabel *chat_title;
50 GtkLabel *chat_subtitle; 54 GtkLabel *chat_subtitle;
51 GtkButton *chat_details_button;
52 55
56 GtkButton *chat_load_button;
57 GtkPopover *chat_load_popover;
58 GtkListBox *chat_load_listbox;
59
60 GtkButton *chat_details_button;
53 GtkLabel *chat_details_label; 61 GtkLabel *chat_details_label;
54 GtkButton *hide_chat_details_button; 62 GtkButton *hide_chat_details_button;
55 GtkBox *chat_details_contacts_box; 63 GtkBox *chat_details_contacts_box;
@@ -81,4 +89,20 @@ ui_chat_update(UI_CHAT_Handle *handle,
81void 89void
82ui_chat_delete(UI_CHAT_Handle *handle); 90ui_chat_delete(UI_CHAT_Handle *handle);
83 91
92void
93ui_chat_add_message(UI_CHAT_Handle *handle,
94 UI_MESSAGE_Handle *message);
95
96void
97ui_chat_remove_message(UI_CHAT_Handle *handle,
98 UI_MESSAGE_Handle *message);
99
100void
101ui_chat_add_file_load(UI_CHAT_Handle *handle,
102 UI_FILE_LOAD_ENTRY_Handle *file_load);
103
104void
105ui_chat_remove_file_load(UI_CHAT_Handle *handle,
106 UI_FILE_LOAD_ENTRY_Handle *file_load);
107
84#endif /* UI_CHAT_H_ */ 108#endif /* UI_CHAT_H_ */
diff --git a/src/ui/chat_entry.c b/src/ui/chat_entry.c
index 1dabec8..c065fc7 100644
--- a/src/ui/chat_entry.c
+++ b/src/ui/chat_entry.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V. 3 Copyright (C) 2021--2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -100,12 +100,12 @@ ui_chat_entry_update(UI_CHAT_ENTRY_Handle *handle,
100 hdy_avatar_set_text(handle->entry_avatar, title); 100 hdy_avatar_set_text(handle->entry_avatar, title);
101 } 101 }
102 102
103 if (!handle->chat) 103 if (!(handle->chat))
104 return; 104 return;
105 105
106 ui_chat_update(handle->chat, app, context); 106 ui_chat_update(handle->chat, app, context);
107 107
108 if (!handle->chat->messages) 108 if (!(handle->chat->messages))
109 return; 109 return;
110 110
111 UI_MESSAGE_Handle *message = ( 111 UI_MESSAGE_Handle *message = (
diff --git a/src/ui/file_load_entry.c b/src/ui/file_load_entry.c
new file mode 100644
index 0000000..a722787
--- /dev/null
+++ b/src/ui/file_load_entry.c
@@ -0,0 +1,90 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file ui/file_load_entry.c
23 */
24
25#include "file_load_entry.h"
26
27#include "../application.h"
28
29#include "chat.h"
30
31static void
32handle_cancel_button_click(GNUNET_UNUSED GtkButton *button,
33 gpointer user_data)
34{
35 UI_FILE_LOAD_ENTRY_Handle* handle = (UI_FILE_LOAD_ENTRY_Handle*) user_data;
36
37 if (handle->chat)
38 ui_chat_remove_file_load(handle->chat, handle);
39
40 // TODO: cancel upload?
41}
42
43UI_FILE_LOAD_ENTRY_Handle*
44ui_file_load_entry_new(MESSENGER_Application *app)
45{
46 UI_FILE_LOAD_ENTRY_Handle* handle = g_malloc(sizeof(UI_FILE_LOAD_ENTRY_Handle));
47
48 handle->chat = NULL;
49
50 handle->builder = gtk_builder_new_from_resource(
51 application_get_resource_path(app, "ui/file_load_entry.ui")
52 );
53
54 handle->entry_box = GTK_WIDGET(
55 gtk_builder_get_object(handle->builder, "entry_box")
56 );
57
58 handle->file_image = GTK_IMAGE(
59 gtk_builder_get_object(handle->builder, "file_image")
60 );
61
62 handle->file_label = GTK_LABEL(
63 gtk_builder_get_object(handle->builder, "file_label")
64 );
65
66 handle->load_progress_bar = GTK_PROGRESS_BAR(
67 gtk_builder_get_object(handle->builder, "load_progress_bar")
68 );
69
70 handle->cancel_button = GTK_BUTTON(
71 gtk_builder_get_object(handle->builder, "cancel_button")
72 );
73
74 g_signal_connect(
75 handle->cancel_button,
76 "clicked",
77 G_CALLBACK(handle_cancel_button_click),
78 handle
79 );
80
81 return handle;
82}
83
84void
85ui_file_load_entry_delete(UI_FILE_LOAD_ENTRY_Handle *handle)
86{
87 g_object_unref(handle->builder);
88
89 g_free(handle);
90}
diff --git a/src/ui/file_load_entry.h b/src/ui/file_load_entry.h
new file mode 100644
index 0000000..f24d3d5
--- /dev/null
+++ b/src/ui/file_load_entry.h
@@ -0,0 +1,56 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file ui/file_load_entry.h
23 */
24
25#ifndef UI_FILE_LOAD_ENTRY_H_
26#define UI_FILE_LOAD_ENTRY_H_
27
28#include <gnunet/gnunet_chat_lib.h>
29
30#include "messenger.h"
31
32typedef struct UI_CHAT_Handle UI_CHAT_Handle;
33
34typedef struct UI_FILE_LOAD_ENTRY_Handle
35{
36 UI_CHAT_Handle *chat;
37
38 GtkBuilder *builder;
39
40 GtkWidget *entry_box;
41
42 GtkImage *file_image;
43 GtkLabel *file_label;
44
45 GtkProgressBar *load_progress_bar;
46
47 GtkButton *cancel_button;
48} UI_FILE_LOAD_ENTRY_Handle;
49
50UI_FILE_LOAD_ENTRY_Handle*
51ui_file_load_entry_new(MESSENGER_Application *app);
52
53void
54ui_file_load_entry_delete(UI_FILE_LOAD_ENTRY_Handle *handle);
55
56#endif /* UI_FILE_LOAD_ENTRY_H_ */
diff --git a/src/ui/new_contact.c b/src/ui/new_contact.c
index 2a030fe..0713aa9 100644
--- a/src/ui/new_contact.c
+++ b/src/ui/new_contact.c
@@ -68,7 +68,7 @@ handle_id_drawing_area_draw(GtkWidget* drawing_area,
68 68
69 GdkPixbuf *image = NULL; 69 GdkPixbuf *image = NULL;
70 70
71 if (!handle->image) 71 if (!(handle->image))
72 return FALSE; 72 return FALSE;
73 73
74 uint w, h; 74 uint w, h;
diff --git a/src/ui/send_file.c b/src/ui/send_file.c
index 7e1e270..d998e24 100644
--- a/src/ui/send_file.c
+++ b/src/ui/send_file.c
@@ -24,7 +24,12 @@
24 24
25#include "send_file.h" 25#include "send_file.h"
26 26
27#include "chat.h"
28#include "chat_entry.h"
29#include "file_load_entry.h"
30
27#include "../application.h" 31#include "../application.h"
32#include "../file.h"
28 33
29static void 34static void
30handle_cancel_button_click(UNUSED GtkButton *button, 35handle_cancel_button_click(UNUSED GtkButton *button,
@@ -36,11 +41,21 @@ handle_cancel_button_click(UNUSED GtkButton *button,
36 41
37static void 42static void
38handle_sending_upload_file(UNUSED void *cls, 43handle_sending_upload_file(UNUSED void *cls,
39 UNUSED const struct GNUNET_CHAT_File *file, 44 const struct GNUNET_CHAT_File *file,
40 uint64_t completed, 45 uint64_t completed,
41 uint64_t size) 46 uint64_t size)
42{ 47{
43 printf("UPLOAD: %lu / %lu\n", completed, size); 48 UI_FILE_LOAD_ENTRY_Handle *file_load = cls;
49
50 gtk_progress_bar_set_fraction(
51 file_load->load_progress_bar,
52 1.0 * completed / size
53 );
54
55 file_update_upload_info(file, completed, size);
56
57 if ((completed >= size) && (file_load->chat))
58 ui_chat_remove_file_load(file_load->chat, file_load);
44} 59}
45 60
46static void 61static void
@@ -67,17 +82,38 @@ handle_send_button_click(GtkButton *button,
67 app->ui.bindings, text_view 82 app->ui.bindings, text_view
68 ); 83 );
69 84
70 if (context) 85 UI_CHAT_ENTRY_Handle *entry = GNUNET_CHAT_context_get_user_pointer(context);
71 GNUNET_CHAT_context_send_file( 86 UI_CHAT_Handle *handle = entry? entry->chat : NULL;
87
88 struct GNUNET_CHAT_File *file = NULL;
89
90 if ((context) && (handle))
91 {
92 UI_FILE_LOAD_ENTRY_Handle *file_load = ui_file_load_entry_new(app);
93
94 gtk_label_set_text(file_load->file_label, filename);
95 gtk_progress_bar_set_fraction(file_load->load_progress_bar, 0.0);
96
97 ui_chat_add_file_load(handle, file_load);
98
99 file = GNUNET_CHAT_context_send_file(
72 context, 100 context,
73 filename, 101 filename,
74 handle_sending_upload_file, 102 handle_sending_upload_file,
75 NULL 103 file_load
76 ); 104 );
105 }
77 106
78 g_free(filename); 107 g_free(filename);
79 108
80 gtk_window_close(GTK_WINDOW(app->ui.send_file.dialog)); 109 gtk_window_close(GTK_WINDOW(app->ui.send_file.dialog));
110
111 if (!file)
112 return;
113
114 file_create_info(file);
115
116 // TODO: create UI component?
81} 117}
82 118
83static void 119static void
@@ -117,7 +153,7 @@ handle_file_drawing_area_draw(GtkWidget* drawing_area,
117 153
118 GdkPixbuf *image = handle->image; 154 GdkPixbuf *image = handle->image;
119 155
120 if (!handle->animation) 156 if (!(handle->animation))
121 goto render_image; 157 goto render_image;
122 158
123 if (handle->animation_iter) 159 if (handle->animation_iter)
@@ -219,7 +255,7 @@ handle_file_chooser_button_file_set(GtkFileChooserButton *file_chooser_button,
219 { 255 {
220 handle->animation = gdk_pixbuf_animation_new_from_file(filename, NULL); 256 handle->animation = gdk_pixbuf_animation_new_from_file(filename, NULL);
221 257
222 if (!handle->animation) 258 if (!(handle->animation))
223 handle->image = gdk_pixbuf_new_from_file(filename, NULL); 259 handle->image = gdk_pixbuf_new_from_file(filename, NULL);
224 260
225 g_free(filename); 261 g_free(filename);
@@ -313,7 +349,7 @@ void
313ui_send_file_dialog_update(UI_SEND_FILE_Handle *handle, 349ui_send_file_dialog_update(UI_SEND_FILE_Handle *handle,
314 const gchar *filename) 350 const gchar *filename)
315{ 351{
316 if (!handle->file_chooser_button) 352 if (!(handle->file_chooser_button))
317 return; 353 return;
318 354
319 gtk_file_chooser_set_filename( 355 gtk_file_chooser_set_filename(