diff options
Diffstat (limited to 'src/ui/chat.c')
-rw-r--r-- | src/ui/chat.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/ui/chat.c b/src/ui/chat.c new file mode 100644 index 0000000..7e5c1fc --- /dev/null +++ b/src/ui/chat.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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/chat.c | ||
23 | */ | ||
24 | |||
25 | #include "chat.h" | ||
26 | |||
27 | #include "messenger.h" | ||
28 | #include "../application.h" | ||
29 | |||
30 | static void | ||
31 | handle_flap_via_button_click(UNUSED GtkButton* button, | ||
32 | gpointer user_data) | ||
33 | { | ||
34 | HdyFlap* flap = HDY_FLAP(user_data); | ||
35 | |||
36 | if (TRUE == hdy_flap_get_reveal_flap(flap)) { | ||
37 | hdy_flap_set_reveal_flap(flap, FALSE); | ||
38 | } else { | ||
39 | hdy_flap_set_reveal_flap(flap, TRUE); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | static void | ||
44 | handle_back_button_click(UNUSED GtkButton* button, | ||
45 | gpointer user_data) | ||
46 | { | ||
47 | HdyLeaflet* leaflet = HDY_LEAFLET(user_data); | ||
48 | |||
49 | GList* children = gtk_container_get_children(GTK_CONTAINER(leaflet)); | ||
50 | |||
51 | if (children) { | ||
52 | hdy_leaflet_set_visible_child(leaflet, GTK_WIDGET(children->data)); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static void | ||
57 | handle_send_text_buffer_changed(GtkTextBuffer *buffer, | ||
58 | gpointer user_data) | ||
59 | { | ||
60 | GtkImage *symbol = GTK_IMAGE(user_data); | ||
61 | |||
62 | GtkTextIter start, end; | ||
63 | gtk_text_buffer_get_start_iter(buffer, &start); | ||
64 | gtk_text_buffer_get_end_iter(buffer, &end); | ||
65 | |||
66 | const gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); | ||
67 | |||
68 | gtk_image_set_from_icon_name( | ||
69 | symbol, | ||
70 | 0 < g_utf8_strlen(text, 1)? | ||
71 | "mail-send-symbolic" : | ||
72 | "audio-input-microphone-symbolic", | ||
73 | GTK_ICON_SIZE_BUTTON | ||
74 | ); | ||
75 | } | ||
76 | |||
77 | static gboolean | ||
78 | _send_text_from_view(MESSENGER_Application *app, | ||
79 | GtkTextView *text_view) | ||
80 | { | ||
81 | GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view); | ||
82 | |||
83 | GtkTextIter start, end; | ||
84 | gtk_text_buffer_get_start_iter(buffer, &start); | ||
85 | gtk_text_buffer_get_end_iter(buffer, &end); | ||
86 | |||
87 | const gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); | ||
88 | |||
89 | if (0 == g_utf8_strlen(text, 1)) | ||
90 | return FALSE; | ||
91 | |||
92 | struct GNUNET_CHAT_Context *context = g_hash_table_lookup( | ||
93 | app->ui.bindings, text_view | ||
94 | ); | ||
95 | |||
96 | if (context) | ||
97 | GNUNET_CHAT_context_send_text(context, text); | ||
98 | |||
99 | gtk_text_buffer_delete(buffer, &start, &end); | ||
100 | return TRUE; | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | handle_send_record_button_click(GtkButton *button, | ||
105 | gpointer user_data) | ||
106 | { | ||
107 | MESSENGER_Application *app = (MESSENGER_Application*) user_data; | ||
108 | |||
109 | GtkTextView *text_view = GTK_TEXT_VIEW( | ||
110 | g_hash_table_lookup(app->ui.bindings, button) | ||
111 | ); | ||
112 | |||
113 | if (!_send_text_from_view(app, text_view)) | ||
114 | { | ||
115 | // TODO: record audio and attach as file? | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static gboolean | ||
120 | handle_send_text_key_press (GtkWidget *widget, | ||
121 | GdkEventKey *event, | ||
122 | gpointer user_data) | ||
123 | { | ||
124 | MESSENGER_Application *app = (MESSENGER_Application*) user_data; | ||
125 | |||
126 | if ((app->ui.mobile) || | ||
127 | (event->state & GDK_SHIFT_MASK) || | ||
128 | ((event->keyval != GDK_KEY_Return) && | ||
129 | (event->keyval != GDK_KEY_KP_Enter))) | ||
130 | return FALSE; | ||
131 | |||
132 | return _send_text_from_view(app, GTK_TEXT_VIEW(widget)); | ||
133 | } | ||
134 | |||
135 | UI_CHAT_Handle* | ||
136 | ui_chat_new(MESSENGER_Application *app) | ||
137 | { | ||
138 | UI_CHAT_Handle *handle = g_malloc(sizeof(UI_CHAT_Handle)); | ||
139 | UI_MESSENGER_Handle *messenger = &(app->ui.messenger); | ||
140 | |||
141 | GtkBuilder* builder = gtk_builder_new_from_file( | ||
142 | "resources/ui/chat.ui" | ||
143 | ); | ||
144 | |||
145 | handle->chat_box = GTK_WIDGET( | ||
146 | gtk_builder_get_object(builder, "chat_box") | ||
147 | ); | ||
148 | |||
149 | handle->back_button = GTK_BUTTON( | ||
150 | gtk_builder_get_object(builder, "back_button") | ||
151 | ); | ||
152 | |||
153 | g_object_bind_property( | ||
154 | messenger->leaflet_chat, | ||
155 | "folded", | ||
156 | handle->back_button, | ||
157 | "visible", | ||
158 | G_BINDING_SYNC_CREATE | ||
159 | ); | ||
160 | |||
161 | g_signal_connect( | ||
162 | handle->back_button, | ||
163 | "clicked", | ||
164 | G_CALLBACK(handle_back_button_click), | ||
165 | messenger->leaflet_chat | ||
166 | ); | ||
167 | |||
168 | handle->chat_title = GTK_LABEL( | ||
169 | gtk_builder_get_object(builder, "chat_title") | ||
170 | ); | ||
171 | |||
172 | handle->chat_subtitle = GTK_LABEL( | ||
173 | gtk_builder_get_object(builder, "chat_subtitle") | ||
174 | ); | ||
175 | |||
176 | handle->chat_details_button = GTK_BUTTON( | ||
177 | gtk_builder_get_object(builder, "chat_details_button") | ||
178 | ); | ||
179 | |||
180 | g_signal_connect( | ||
181 | handle->chat_details_button, | ||
182 | "clicked", | ||
183 | G_CALLBACK(handle_flap_via_button_click), | ||
184 | messenger->flap_chat_details | ||
185 | ); | ||
186 | |||
187 | handle->messages_listbox = GTK_LIST_BOX( | ||
188 | gtk_builder_get_object(builder, "messages_listbox") | ||
189 | ); | ||
190 | |||
191 | handle->attach_file_button = GTK_BUTTON( | ||
192 | gtk_builder_get_object(builder, "attach_file_button") | ||
193 | ); | ||
194 | |||
195 | handle->send_text_view = GTK_TEXT_VIEW( | ||
196 | gtk_builder_get_object(builder, "send_text_view") | ||
197 | ); | ||
198 | |||
199 | handle->emoji_button = GTK_BUTTON( | ||
200 | gtk_builder_get_object(builder, "emoji_button") | ||
201 | ); | ||
202 | |||
203 | handle->send_record_button = GTK_BUTTON( | ||
204 | gtk_builder_get_object(builder, "send_record_button") | ||
205 | ); | ||
206 | |||
207 | handle->send_record_symbol = GTK_IMAGE( | ||
208 | gtk_builder_get_object(builder, "send_record_symbol") | ||
209 | ); | ||
210 | |||
211 | GtkTextBuffer *send_text_buffer = gtk_text_view_get_buffer( | ||
212 | handle->send_text_view | ||
213 | ); | ||
214 | |||
215 | g_signal_connect( | ||
216 | send_text_buffer, | ||
217 | "changed", | ||
218 | G_CALLBACK(handle_send_text_buffer_changed), | ||
219 | handle->send_record_symbol | ||
220 | ); | ||
221 | |||
222 | g_signal_connect( | ||
223 | handle->send_record_button, | ||
224 | "clicked", | ||
225 | G_CALLBACK(handle_send_record_button_click), | ||
226 | app | ||
227 | ); | ||
228 | |||
229 | g_signal_connect( | ||
230 | handle->send_text_view, | ||
231 | "key-press-event", | ||
232 | G_CALLBACK(handle_send_text_key_press), | ||
233 | app | ||
234 | ); | ||
235 | |||
236 | g_hash_table_insert( | ||
237 | app->ui.bindings, | ||
238 | handle->send_record_button, | ||
239 | handle->send_text_view | ||
240 | ); | ||
241 | |||
242 | return handle; | ||
243 | } | ||
244 | |||
245 | void | ||
246 | ui_chat_delete(UI_CHAT_Handle *handle) | ||
247 | { | ||
248 | g_free(handle); | ||
249 | } | ||