blob: 16637296a373d473205dd0cce9c4831281c3c152 [file] [log] [blame]
aviau039001d2016-09-29 16:39:05 -04001/*
Guillaume Roguez2a6150d2017-07-19 18:24:47 -04002 * Copyright (C) 2016-2017 Savoir-faire Linux Inc.
aviau039001d2016-09-29 16:39:05 -04003 * Author: Alexandre Viau <alexandre.viau@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "webkitchatcontainer.h"
21
22// GTK+ related
23#include <gtk/gtk.h>
aviau039001d2016-09-29 16:39:05 -040024#include <webkit2/webkit2.h>
25
26// Qt
27#include <QtCore/QJsonValue>
28#include <QtCore/QJsonObject>
29#include <QtCore/QJsonDocument>
30
31// LRC
32#include <media/textrecording.h>
33#include <globalinstances.h>
aviaufc213552016-11-01 12:39:39 -040034#include <contactmethod.h>
aviau039001d2016-09-29 16:39:05 -040035
36// Ring Client
37#include "native/pixbufmanipulator.h"
38#include "config.h"
39
40struct _WebKitChatContainer
41{
42 GtkBox parent;
43};
44
45struct _WebKitChatContainerClass
46{
47 GtkBoxClass parent_class;
48};
49
50typedef struct _WebKitChatContainerPrivate WebKitChatContainerPrivate;
51
52struct _WebKitChatContainerPrivate
53{
54 GtkWidget* webview_chat;
aviau32b8dd62016-11-02 00:36:57 -040055 GtkWidget* box_webview_chat;
aviau039001d2016-09-29 16:39:05 -040056
57 bool chatview_debug;
58
59 /* Array of javascript libraries to load. Used during initialization */
60 GList* js_libs_to_load;
61 gboolean js_libs_loaded;
62};
63
64G_DEFINE_TYPE_WITH_PRIVATE(WebKitChatContainer, webkit_chat_container, GTK_TYPE_BOX);
65
66#define WEBKIT_CHAT_CONTAINER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), WEBKIT_CHAT_CONTAINER_TYPE, WebKitChatContainerPrivate))
67
68/* signals */
69enum {
70 READY,
AmarOkb4253242017-07-13 11:21:39 -040071 SEND_MESSAGE,
aviau039001d2016-09-29 16:39:05 -040072 LAST_SIGNAL
73};
74
75static guint webkit_chat_container_signals[LAST_SIGNAL] = { 0 };
76
Stepan Salenikovich1cf35e52017-05-03 16:12:11 -040077/* functions */
78static gboolean webview_crashed(WebKitChatContainer *self);
79
aviau039001d2016-09-29 16:39:05 -040080static void
81webkit_chat_container_dispose(GObject *object)
82{
83 G_OBJECT_CLASS(webkit_chat_container_parent_class)->dispose(object);
84}
85
86static void
87webkit_chat_container_init(WebKitChatContainer *view)
88{
89 gtk_widget_init_template(GTK_WIDGET(view));
90}
91
92static void
93webkit_chat_container_class_init(WebKitChatContainerClass *klass)
94{
95 G_OBJECT_CLASS(klass)->dispose = webkit_chat_container_dispose;
96
aviau039001d2016-09-29 16:39:05 -040097 gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
98 "/cx/ring/RingGnome/webkitchatcontainer.ui");
99
aviau32b8dd62016-11-02 00:36:57 -0400100 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), WebKitChatContainer, box_webview_chat);
aviau039001d2016-09-29 16:39:05 -0400101
102 /* add signals */
103 webkit_chat_container_signals[READY] = g_signal_new("ready",
104 G_TYPE_FROM_CLASS(klass),
105 (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
106 0,
107 nullptr,
108 nullptr,
109 g_cclosure_marshal_VOID__VOID,
110 G_TYPE_NONE, 0);
AmarOkb4253242017-07-13 11:21:39 -0400111
112 webkit_chat_container_signals[SEND_MESSAGE] = g_signal_new("send-message",
113 G_TYPE_FROM_CLASS(klass),
114 (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED),
115 0,
116 nullptr,
117 nullptr,
118 g_cclosure_marshal_VOID__STRING,
119 G_TYPE_NONE, 1, G_TYPE_STRING);
aviau039001d2016-09-29 16:39:05 -0400120}
121
122static gboolean
AmarOk748d6cd2017-07-18 12:23:42 -0400123webview_chat_context_menu(WebKitChatContainer *self,
124 WebKitContextMenu *menu,
125 GdkEvent *event,
126 WebKitHitTestResult *hit_test_result,
127 gpointer user_data)
aviau039001d2016-09-29 16:39:05 -0400128{
AmarOk748d6cd2017-07-18 12:23:42 -0400129 GList *items, *nextList;
130 for (items = webkit_context_menu_get_items(menu) ; items ; items = nextList) {
131 WebKitContextMenuAction action;
132 nextList = items->next;
133 auto item = (WebKitContextMenuItem*)items->data;
134 action = webkit_context_menu_item_get_stock_action(item);
135
136 if (action == WEBKIT_CONTEXT_MENU_ACTION_RELOAD ||
137 action == WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD ||
138 action == WEBKIT_CONTEXT_MENU_ACTION_GO_BACK ||
139 action == WEBKIT_CONTEXT_MENU_ACTION_STOP) {
140 webkit_context_menu_remove(menu, item);
141 }
142 }
143 return false;
aviau039001d2016-09-29 16:39:05 -0400144}
145
146QString
147message_index_to_json_message_object(const QModelIndex &idx)
148{
149 auto message = idx.data().value<QString>();
150 auto sender = idx.data(static_cast<int>(Media::TextRecording::Role::AuthorDisplayname)).value<QString>();
aviaufc213552016-11-01 12:39:39 -0400151 auto sender_contact_method = idx.data(static_cast<int>(Media::TextRecording::Role::ContactMethod)).value<ContactMethod*>();
aviau039001d2016-09-29 16:39:05 -0400152 auto timestamp = idx.data(static_cast<int>(Media::TextRecording::Role::Timestamp)).value<time_t>();
153 auto direction = idx.data(static_cast<int>(Media::TextRecording::Role::Direction)).value<Media::Media::Direction>();
154 auto message_id = idx.row();
155
aviaufc213552016-11-01 12:39:39 -0400156 QString sender_contact_method_str;
157 if(direction == Media::Media::Direction::IN)
158 {
159 sender_contact_method_str = QString(g_strdup_printf("%p", sender_contact_method));
160 }
161 else
162 {
163 sender_contact_method_str = "self";
164 }
165
aviau039001d2016-09-29 16:39:05 -0400166 QJsonObject message_object = QJsonObject();
167 message_object.insert("text", QJsonValue(message));
168 message_object.insert("id", QJsonValue(QString().setNum(message_id)));
169 message_object.insert("sender", QJsonValue(sender));
aviaufc213552016-11-01 12:39:39 -0400170 message_object.insert("sender_contact_method", QJsonValue(sender_contact_method_str));
aviau039001d2016-09-29 16:39:05 -0400171 message_object.insert("timestamp", QJsonValue((int) timestamp));
172 message_object.insert("direction", QJsonValue((direction == Media::Media::Direction::IN) ? "in" : "out"));
173
174 switch(idx.data(static_cast<int>(Media::TextRecording::Role::DeliveryStatus)).value<Media::TextRecording::Status>())
175 {
176 case Media::TextRecording::Status::FAILURE:
177 {
178 message_object.insert("delivery_status", QJsonValue("failure"));
179 break;
180 }
181 case Media::TextRecording::Status::COUNT__:
182 {
183 message_object.insert("delivery_status", QJsonValue("count__"));
184 break;
185 }
186 case Media::TextRecording::Status::SENDING:
187 {
188 message_object.insert("delivery_status", QJsonValue("sending"));
189 break;
190 }
191 case Media::TextRecording::Status::UNKNOWN:
192 {
193 message_object.insert("delivery_status", QJsonValue("unknown"));
194 break;
195 }
196 case Media::TextRecording::Status::READ:
197 {
198 message_object.insert("delivery_status", QJsonValue("read"));
199 break;
200 }
201 case Media::TextRecording::Status::SENT:
202 {
203 message_object.insert("delivery_status", QJsonValue("sent"));
204 break;
205 }
206 }
207
208 return QString(QJsonDocument(message_object).toJson(QJsonDocument::Compact));
209}
210
Stepan Salenikovichb52dbc52016-12-27 14:05:39 -0500211#if WEBKIT_CHECK_VERSION(2, 6, 0)
aviau039001d2016-09-29 16:39:05 -0400212static gboolean
213webview_chat_decide_policy (G_GNUC_UNUSED WebKitWebView *web_view,
214 WebKitPolicyDecision *decision,
215 WebKitPolicyDecisionType type)
216{
217 switch (type)
218 {
219 case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
220 case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
221 {
222 WebKitNavigationPolicyDecision* navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION(decision);
223 WebKitNavigationAction* navigation_action = webkit_navigation_policy_decision_get_navigation_action(navigation_decision);
224 WebKitNavigationType navigation_type = webkit_navigation_action_get_navigation_type(navigation_action);
225
226 switch (navigation_type)
227 {
228 case WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED:
229 case WEBKIT_NAVIGATION_TYPE_BACK_FORWARD:
230 case WEBKIT_NAVIGATION_TYPE_RELOAD:
231 case WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED:
232 case WEBKIT_NAVIGATION_TYPE_OTHER:
233 {
234 /* make no decision */
235 return FALSE;
236
237 }
238 case WEBKIT_NAVIGATION_TYPE_LINK_CLICKED:
239 {
240 webkit_policy_decision_ignore(decision);
241
242 WebKitURIRequest* uri_request = webkit_navigation_action_get_request(navigation_action);
243 const gchar* uri = webkit_uri_request_get_uri(uri_request);
244
245 gtk_show_uri(NULL, uri, GDK_CURRENT_TIME, NULL);
246 }
247 }
248
249 webkit_policy_decision_ignore(decision);
250 break;
251 }
252 case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
253 {
254 //WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision);
255 //break;
256 return FALSE;
257 }
258 default:
259 {
260 /* Making no decision results in webkit_policy_decision_use(). */
261 return FALSE;
262 }
263 }
264 return TRUE;
265}
266#endif
267
AmarOkb4253242017-07-13 11:21:39 -0400268static gboolean
269webview_send_text(WebKitWebView *self,
270 WebKitScriptDialog *dialog,
271 gpointer user_data)
272{
273 auto message = webkit_script_dialog_get_message(dialog);
274 g_signal_emit(G_OBJECT(self), webkit_chat_container_signals[SEND_MESSAGE], 0, message);
275 return true;
276}
277
aviau039001d2016-09-29 16:39:05 -0400278static void
279javascript_library_loaded(WebKitWebView *webview_chat,
280 GAsyncResult *result,
281 WebKitChatContainer* self)
282{
283 g_return_if_fail(IS_WEBKIT_CHAT_CONTAINER(self));
284 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(self);
285
286 auto loaded_library = g_list_first(priv->js_libs_to_load);
287
288 GError *error = NULL;
289 WebKitJavascriptResult* js_result = webkit_web_view_run_javascript_from_gresource_finish(webview_chat, result, &error);
290 if (!js_result) {
291 g_warning("Error loading %s: %s", (const gchar*) loaded_library->data, error->message);
292 g_error_free(error);
293 g_object_unref(self);
294 /* Stop loading view, most likely resulting in a blank page */
295 return;
296 }
297 webkit_javascript_result_unref(js_result);
298
299 priv->js_libs_to_load = g_list_remove(priv->js_libs_to_load, loaded_library->data);
300
301 if(g_list_length(priv->js_libs_to_load) > 0)
302 {
303 /* keep loading... */
304 webkit_web_view_run_javascript_from_gresource(
305 webview_chat,
306 (const gchar*) g_list_first(priv->js_libs_to_load)->data,
307 NULL,
308 (GAsyncReadyCallback) javascript_library_loaded,
309 self
310 );
311 }
312 else
313 {
314 priv->js_libs_loaded = TRUE;
315 g_signal_emit(G_OBJECT(self), webkit_chat_container_signals[READY], 0);
316
317 /* The view could now be deleted without causing a crash */
318 g_object_unref(self);
319 }
320}
321
322static void
323load_javascript_libs(WebKitWebView *webview_chat,
324 WebKitChatContainer* self)
325{
326 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(self);
327
328 /* Create the list of libraries to load */
aviau039001d2016-09-29 16:39:05 -0400329 priv->js_libs_to_load = g_list_append(priv->js_libs_to_load, (gchar*) "/cx/ring/RingGnome/linkify.js");
330 priv->js_libs_to_load = g_list_append(priv->js_libs_to_load, (gchar*) "/cx/ring/RingGnome/linkify-string.js");
331 priv->js_libs_to_load = g_list_append(priv->js_libs_to_load, (gchar*) "/cx/ring/RingGnome/linkify-html.js");
aviau039001d2016-09-29 16:39:05 -0400332
333 /* ref the chat view so that its not destroyed while we load
334 * we will unref in javascript_library_loaded
335 */
336 g_object_ref(self);
337
338 /* start loading */
339 webkit_web_view_run_javascript_from_gresource(
340 WEBKIT_WEB_VIEW(webview_chat),
341 (const gchar*) g_list_first(priv->js_libs_to_load)->data,
342 NULL,
343 (GAsyncReadyCallback) javascript_library_loaded,
344 self
345 );
346}
347
348static void
349webview_chat_load_changed(WebKitWebView *webview_chat,
350 WebKitLoadEvent load_event,
351 WebKitChatContainer* self)
352{
353 switch (load_event) {
354 case WEBKIT_LOAD_REDIRECTED:
355 {
356 g_warning("webview_chat load is being redirected, this should not happen");
357 }
358 case WEBKIT_LOAD_STARTED:
359 case WEBKIT_LOAD_COMMITTED:
360 {
361 break;
362 }
363 case WEBKIT_LOAD_FINISHED:
364 {
365 load_javascript_libs(webview_chat, self);
366 //TODO: disconnect? It shouldn't happen more than once
367 break;
368 }
369 }
370}
371
372static void
373build_view(WebKitChatContainer *view)
374{
375 g_return_if_fail(IS_WEBKIT_CHAT_CONTAINER(view));
376 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
377
aviau039001d2016-09-29 16:39:05 -0400378 priv->chatview_debug = FALSE;
379 auto ring_chatview_debug = g_getenv("RING_CHATVIEW_DEBUG");
380 if (ring_chatview_debug || g_strcmp0(ring_chatview_debug, "true") == 0)
381 {
382 priv->chatview_debug = TRUE;
383 }
384
aviau32b8dd62016-11-02 00:36:57 -0400385 /* Prepare WebKitUserContentManager */
386 WebKitUserContentManager* webkit_content_manager = webkit_user_content_manager_new();
387
388 WebKitUserStyleSheet* chatview_style_sheet = webkit_user_style_sheet_new(
389 (gchar*) g_bytes_get_data(
390 g_resources_lookup_data(
391 "/cx/ring/RingGnome/chatview.css",
392 G_RESOURCE_LOOKUP_FLAGS_NONE,
393 NULL
394 ),
395 NULL
396 ),
397 WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
398 WEBKIT_USER_STYLE_LEVEL_USER,
399 NULL,
400 NULL
401 );
402 webkit_user_content_manager_add_style_sheet(webkit_content_manager, chatview_style_sheet);
403
404 /* Prepare WebKitSettings */
aviau039001d2016-09-29 16:39:05 -0400405 WebKitSettings* webkit_settings = webkit_settings_new_with_settings(
406 "enable-javascript", TRUE,
407 "enable-developer-extras", priv->chatview_debug,
408 "enable-java", FALSE,
409 "enable-plugins", FALSE,
410 "enable-site-specific-quirks", FALSE,
411 "enable-smooth-scrolling", TRUE,
412 NULL
413 );
aviau32b8dd62016-11-02 00:36:57 -0400414
415 /* Create the WebKitWebView */
416 priv->webview_chat = GTK_WIDGET(
417 webkit_web_view_new_with_user_content_manager(
418 webkit_content_manager
419 )
420 );
421
422 gtk_container_add(GTK_CONTAINER(priv->box_webview_chat), priv->webview_chat);
423 gtk_widget_show(priv->webview_chat);
424 gtk_widget_set_vexpand(GTK_WIDGET(priv->webview_chat), TRUE);
425 gtk_widget_set_hexpand(GTK_WIDGET(priv->webview_chat), TRUE);
426
427 /* Set the WebKitSettings */
aviau039001d2016-09-29 16:39:05 -0400428 webkit_web_view_set_settings(WEBKIT_WEB_VIEW(priv->webview_chat), webkit_settings);
429
Sébastien Blinc5e68372017-07-26 12:48:01 -0400430 gtk_drag_dest_unset(priv->webview_chat); // remove drag and drop to prevent unwanted reloading
aviau039001d2016-09-29 16:39:05 -0400431 g_signal_connect(priv->webview_chat, "load-changed", G_CALLBACK(webview_chat_load_changed), view);
432 g_signal_connect_swapped(priv->webview_chat, "context-menu", G_CALLBACK(webview_chat_context_menu), view);
AmarOkb4253242017-07-13 11:21:39 -0400433 g_signal_connect_swapped(priv->webview_chat, "script-dialog", G_CALLBACK(webview_send_text), view);
Stepan Salenikovichb52dbc52016-12-27 14:05:39 -0500434#if WEBKIT_CHECK_VERSION(2, 6, 0)
aviau039001d2016-09-29 16:39:05 -0400435 g_signal_connect(priv->webview_chat, "decide-policy", G_CALLBACK(webview_chat_decide_policy), view);
436#endif
437
438 GBytes* chatview_bytes = g_resources_lookup_data(
439 "/cx/ring/RingGnome/chatview.html",
440 G_RESOURCE_LOOKUP_FLAGS_NONE,
441 NULL
442 );
443
444 webkit_web_view_load_html(
445 WEBKIT_WEB_VIEW(priv->webview_chat),
446 (gchar*) g_bytes_get_data(chatview_bytes, NULL),
447 NULL
448 );
449
450 /* Now we wait for the load-changed event, before we
451 * start loading javascript libraries */
Stepan Salenikovich1cf35e52017-05-03 16:12:11 -0400452
453 /* handle web view crash */
454 g_signal_connect_swapped(priv->webview_chat, "web-process-crashed", G_CALLBACK(webview_crashed), view);
455}
456
457static gboolean
458webview_crashed(WebKitChatContainer *self)
459{
460 g_warning("Gtk Web Process crashed! Re-createing web view");
461
462 auto priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(self);
463
464 /* make sure we destroy previous WebView */
465 if (priv->webview_chat) {
466 gtk_widget_destroy(priv->webview_chat);
467 priv->webview_chat = nullptr;
468 }
469
470 build_view(self);
471
472 return G_SOURCE_CONTINUE;
aviau039001d2016-09-29 16:39:05 -0400473}
474
475GtkWidget *
476webkit_chat_container_new()
477{
478 gpointer view = g_object_new(WEBKIT_CHAT_CONTAINER_TYPE, NULL);
479
480 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
481 priv->js_libs_loaded = FALSE;
482
483 build_view(WEBKIT_CHAT_CONTAINER(view));
484
485 return (GtkWidget *)view;
486}
487
488void
Sébastien Blin70dc0b72017-07-31 16:24:41 -0400489webkit_chat_container_set_display_links(WebKitChatContainer *view, bool display)
490{
491 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
492 gchar* function_call = g_strdup_printf("ring.chatview.setDisplayLinks(%s);",
493 display ? "true" : "false");
494
495 webkit_web_view_run_javascript(
496 WEBKIT_WEB_VIEW(priv->webview_chat),
497 function_call,
498 NULL,
499 NULL,
500 NULL
501 );
502}
503
504void
aviaufc213552016-11-01 12:39:39 -0400505webkit_chat_container_clear_sender_images(WebKitChatContainer *view)
506{
507 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
508
509 webkit_web_view_run_javascript(
510 WEBKIT_WEB_VIEW(priv->webview_chat),
511 "ring.chatview.clearSenderImages()",
512 NULL,
513 NULL,
514 NULL
515 );
516}
517
518void
aviau039001d2016-09-29 16:39:05 -0400519webkit_chat_container_clear(WebKitChatContainer *view)
520{
521 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
522
523 webkit_web_view_run_javascript(
524 WEBKIT_WEB_VIEW(priv->webview_chat),
525 "ring.chatview.clearMessages()",
526 NULL,
527 NULL,
528 NULL
529 );
530
aviaufc213552016-11-01 12:39:39 -0400531 webkit_chat_container_clear_sender_images(view);
aviau039001d2016-09-29 16:39:05 -0400532}
533
534void
535webkit_chat_container_print_new_message(WebKitChatContainer *view, const QModelIndex &idx)
536{
537 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
538
Guillaume Roguez1820ba12017-03-28 16:30:36 -0400539 auto message_object = message_index_to_json_message_object(idx).toUtf8();
540 gchar* function_call = g_strdup_printf("ring.chatview.addMessage(%s);", message_object.constData());
aviau039001d2016-09-29 16:39:05 -0400541 webkit_web_view_run_javascript(
542 WEBKIT_WEB_VIEW(priv->webview_chat),
543 function_call,
544 NULL,
545 NULL,
546 NULL
547 );
548 g_free(function_call);
549}
550
551void
552webkit_chat_container_update_message(WebKitChatContainer *view, const QModelIndex &idx)
553{
554 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
555
Guillaume Roguez1820ba12017-03-28 16:30:36 -0400556 auto message_object = message_index_to_json_message_object(idx).toUtf8();
557 gchar* function_call = g_strdup_printf("ring.chatview.updateMessage(%s);", message_object.constData());
aviau039001d2016-09-29 16:39:05 -0400558 webkit_web_view_run_javascript(
559 WEBKIT_WEB_VIEW(priv->webview_chat),
560 function_call,
561 NULL,
562 NULL,
563 NULL
564 );
565 g_free(function_call);
566}
567
568void
aviaufc213552016-11-01 12:39:39 -0400569webkit_chat_container_set_sender_image(WebKitChatContainer *view, ContactMethod *sender_contact_method, QVariant sender_image)
aviau039001d2016-09-29 16:39:05 -0400570{
571 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
572
aviaufc213552016-11-01 12:39:39 -0400573 /* The sender_contact_method should be set to nullptr if the sender is self */
574 QString sender_contact_method_str;
575 if (sender_contact_method)
576 {
aviauac74ac32016-11-03 17:25:11 -0400577 sender_contact_method_str = QString().sprintf("%p", sender_contact_method);
aviaufc213552016-11-01 12:39:39 -0400578 }
579 else
580 {
581 sender_contact_method_str = "self";
582 }
583
aviau039001d2016-09-29 16:39:05 -0400584 auto sender_image_base64 = (QString) GlobalInstances::pixmapManipulator().toByteArray(sender_image).toBase64();
585
586 QJsonObject set_sender_image_object = QJsonObject();
aviaufc213552016-11-01 12:39:39 -0400587 set_sender_image_object.insert("sender_contact_method", QJsonValue(sender_contact_method_str));
aviau039001d2016-09-29 16:39:05 -0400588 set_sender_image_object.insert("sender_image", QJsonValue(sender_image_base64));
589
Stepan Salenikovich407dc412016-11-29 11:01:31 -0500590 auto set_sender_image_object_string = QString(QJsonDocument(set_sender_image_object).toJson(QJsonDocument::Compact));
aviau039001d2016-09-29 16:39:05 -0400591
Stepan Salenikovich407dc412016-11-29 11:01:31 -0500592 gchar* function_call = g_strdup_printf("ring.chatview.setSenderImage(%s);", set_sender_image_object_string.toUtf8().constData());
aviau039001d2016-09-29 16:39:05 -0400593 webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(priv->webview_chat), function_call, NULL, NULL, NULL);
594 g_free(function_call);
595}
596
597gboolean
598webkit_chat_container_is_ready(WebKitChatContainer *view)
599{
600 WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
601 return priv->js_libs_loaded;
602}