Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 1 | /* |
Guillaume Roguez | 77c579d | 2018-01-30 15:54:02 -0500 | [diff] [blame] | 2 | * Copyright (C) 2016-2018 Savoir-faire Linux Inc. |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 3 | * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com> |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 4 | * Author: Alexandre Viau <alexandre.viau@savoirfairelinux.com> |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 5 | * Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com> |
| 6 | * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 3 of the License, or |
| 11 | * (at your option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program; if not, write to the Free Software |
| 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 21 | */ |
| 22 | |
| 23 | #include "chatview.h" |
| 24 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 25 | // std |
| 26 | #include <algorithm> |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 27 | |
Nicolas Jager | 759faea | 2017-03-22 16:22:00 -0400 | [diff] [blame] | 28 | // LRC |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 29 | #include <api/contactmodel.h> |
| 30 | #include <api/conversationmodel.h> |
| 31 | #include <api/contact.h> |
Nicolas Jager | 759faea | 2017-03-22 16:22:00 -0400 | [diff] [blame] | 32 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 33 | // Client |
| 34 | #include "utils/files.h" |
Stepan Salenikovich | ce06adb | 2016-02-19 12:53:53 -0500 | [diff] [blame] | 35 | |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 36 | struct _ChatView |
| 37 | { |
| 38 | GtkBox parent; |
| 39 | }; |
| 40 | |
| 41 | struct _ChatViewClass |
| 42 | { |
| 43 | GtkBoxClass parent_class; |
| 44 | }; |
| 45 | |
| 46 | typedef struct _ChatViewPrivate ChatViewPrivate; |
| 47 | |
| 48 | struct _ChatViewPrivate |
| 49 | { |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 50 | GtkWidget *box_webkit_chat_container; |
| 51 | GtkWidget *webkit_chat_container; |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 52 | GtkWidget *hbox_chat_info; |
| 53 | GtkWidget *label_peer; |
AmarOk | cba0395 | 2017-07-17 10:13:49 -0400 | [diff] [blame] | 54 | GtkWidget *label_cm; |
Stepan Salenikovich | 8043a56 | 2016-03-18 13:56:40 -0400 | [diff] [blame] | 55 | GtkWidget *button_close_chatview; |
Stepan Salenikovich | e993324 | 2016-06-21 18:08:48 -0400 | [diff] [blame] | 56 | GtkWidget *button_placecall; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 57 | GtkWidget *button_add_to_conversations; |
Nicolas Jager | d29ae95 | 2017-12-04 16:00:12 -0500 | [diff] [blame] | 58 | GtkWidget *button_place_audio_call; |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 59 | |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 60 | GSettings *settings; |
| 61 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 62 | lrc::api::conversation::Info* conversation_; |
| 63 | AccountContainer* accountContainer_; |
| 64 | bool isTemporary_; |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 65 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 66 | QMetaObject::Connection new_interaction_connection; |
| 67 | QMetaObject::Connection update_interaction_connection; |
| 68 | QMetaObject::Connection update_add_to_conversations; |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 69 | |
| 70 | gulong webkit_ready; |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 71 | gulong webkit_send_text; |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 72 | }; |
| 73 | |
| 74 | G_DEFINE_TYPE_WITH_PRIVATE(ChatView, chat_view, GTK_TYPE_BOX); |
| 75 | |
| 76 | #define CHAT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAT_VIEW_TYPE, ChatViewPrivate)) |
| 77 | |
| 78 | enum { |
| 79 | NEW_MESSAGES_DISPLAYED, |
Stepan Salenikovich | 8043a56 | 2016-03-18 13:56:40 -0400 | [diff] [blame] | 80 | HIDE_VIEW_CLICKED, |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 81 | LAST_SIGNAL |
| 82 | }; |
| 83 | |
| 84 | static guint chat_view_signals[LAST_SIGNAL] = { 0 }; |
| 85 | |
| 86 | static void |
| 87 | chat_view_dispose(GObject *object) |
| 88 | { |
| 89 | ChatView *view; |
| 90 | ChatViewPrivate *priv; |
| 91 | |
| 92 | view = CHAT_VIEW(object); |
| 93 | priv = CHAT_VIEW_GET_PRIVATE(view); |
| 94 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 95 | QObject::disconnect(priv->new_interaction_connection); |
| 96 | QObject::disconnect(priv->update_interaction_connection); |
| 97 | QObject::disconnect(priv->update_add_to_conversations); |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 98 | |
| 99 | /* Destroying the box will also destroy its children, and we wouldn't |
| 100 | * want that. So we remove the webkit_chat_container from the box. */ |
| 101 | if (priv->webkit_chat_container) { |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 102 | /* disconnect for webkit signals */ |
| 103 | g_signal_handler_disconnect(priv->webkit_chat_container, priv->webkit_ready); |
| 104 | priv->webkit_ready = 0; |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 105 | g_signal_handler_disconnect(priv->webkit_chat_container, priv->webkit_send_text); |
| 106 | priv->webkit_send_text = 0; |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 107 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 108 | gtk_container_remove( |
| 109 | GTK_CONTAINER(priv->box_webkit_chat_container), |
| 110 | GTK_WIDGET(priv->webkit_chat_container) |
| 111 | ); |
| 112 | priv->webkit_chat_container = nullptr; |
| 113 | } |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 114 | |
| 115 | G_OBJECT_CLASS(chat_view_parent_class)->dispose(object); |
| 116 | } |
| 117 | |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 118 | static void |
Stepan Salenikovich | 8043a56 | 2016-03-18 13:56:40 -0400 | [diff] [blame] | 119 | hide_chat_view(G_GNUC_UNUSED GtkWidget *widget, ChatView *self) |
| 120 | { |
| 121 | g_signal_emit(G_OBJECT(self), chat_view_signals[HIDE_VIEW_CLICKED], 0); |
| 122 | } |
| 123 | |
| 124 | static void |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 125 | display_links_toggled(ChatView *self) |
| 126 | { |
| 127 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
| 128 | if (priv->webkit_chat_container) { |
| 129 | webkit_chat_container_set_display_links( |
| 130 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 131 | g_settings_get_boolean(priv->settings, "enable-display-links") |
| 132 | ); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | static void |
Stepan Salenikovich | e993324 | 2016-06-21 18:08:48 -0400 | [diff] [blame] | 137 | placecall_clicked(ChatView *self) |
| 138 | { |
| 139 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 140 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 141 | priv->accountContainer_->info.conversationModel->placeCall(priv->conversation_->uid); |
Stepan Salenikovich | e993324 | 2016-06-21 18:08:48 -0400 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | static void |
Nicolas Jager | d29ae95 | 2017-12-04 16:00:12 -0500 | [diff] [blame] | 145 | place_audio_call_clicked(ChatView *self) |
| 146 | { |
| 147 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
| 148 | |
| 149 | if (!priv->conversation_) |
| 150 | return; |
| 151 | |
| 152 | priv->accountContainer_->info.conversationModel->placeAudioOnlyCall(priv->conversation_->uid); |
| 153 | } |
| 154 | |
| 155 | static void |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 156 | button_add_to_conversations_clicked(ChatView *self) |
Nicolas Jager | 759faea | 2017-03-22 16:22:00 -0400 | [diff] [blame] | 157 | { |
| 158 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 159 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 160 | priv->accountContainer_->info.conversationModel->makePermanent(priv->conversation_->uid); |
Nicolas Jager | 759faea | 2017-03-22 16:22:00 -0400 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | static void |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 164 | webkit_chat_container_script_dialog(G_GNUC_UNUSED GtkWidget* webview, gchar *interaction, ChatView* self) |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 165 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 166 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
| 167 | auto order = std::string(interaction); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 168 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 169 | if (order == "ACCEPT") { |
| 170 | priv->accountContainer_->info.conversationModel->makePermanent(priv->conversation_->uid); |
| 171 | } else if (order == "REFUSE") { |
| 172 | priv->accountContainer_->info.conversationModel->removeConversation(priv->conversation_->uid); |
| 173 | } else if (order == "BLOCK") { |
| 174 | priv->accountContainer_->info.conversationModel->removeConversation(priv->conversation_->uid, true); |
| 175 | } else if (order.find("SEND:") == 0) { |
| 176 | // Get text body |
| 177 | auto toSend = order.substr(std::string("SEND:").size()); |
| 178 | priv->accountContainer_->info.conversationModel->sendMessage(priv->conversation_->uid, toSend); |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 179 | } |
| 180 | } |
| 181 | |
| 182 | static void |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 183 | chat_view_init(ChatView *view) |
| 184 | { |
| 185 | gtk_widget_init_template(GTK_WIDGET(view)); |
| 186 | |
| 187 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(view); |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 188 | priv->settings = g_settings_new_full(get_ring_schema(), NULL, NULL); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 189 | |
Stepan Salenikovich | 8043a56 | 2016-03-18 13:56:40 -0400 | [diff] [blame] | 190 | g_signal_connect(priv->button_close_chatview, "clicked", G_CALLBACK(hide_chat_view), view); |
Stepan Salenikovich | e993324 | 2016-06-21 18:08:48 -0400 | [diff] [blame] | 191 | g_signal_connect_swapped(priv->button_placecall, "clicked", G_CALLBACK(placecall_clicked), view); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 192 | g_signal_connect_swapped(priv->button_add_to_conversations, "clicked", G_CALLBACK(button_add_to_conversations_clicked), view); |
Nicolas Jager | d29ae95 | 2017-12-04 16:00:12 -0500 | [diff] [blame] | 193 | g_signal_connect_swapped(priv->button_place_audio_call, "clicked", G_CALLBACK(place_audio_call_clicked), view); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | static void |
| 197 | chat_view_class_init(ChatViewClass *klass) |
| 198 | { |
| 199 | G_OBJECT_CLASS(klass)->dispose = chat_view_dispose; |
| 200 | |
| 201 | gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass), |
| 202 | "/cx/ring/RingGnome/chatview.ui"); |
| 203 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 204 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, box_webkit_chat_container); |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 205 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, hbox_chat_info); |
| 206 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, label_peer); |
AmarOk | cba0395 | 2017-07-17 10:13:49 -0400 | [diff] [blame] | 207 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, label_cm); |
Stepan Salenikovich | 8043a56 | 2016-03-18 13:56:40 -0400 | [diff] [blame] | 208 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_close_chatview); |
Stepan Salenikovich | e993324 | 2016-06-21 18:08:48 -0400 | [diff] [blame] | 209 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_placecall); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 210 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_add_to_conversations); |
Nicolas Jager | d29ae95 | 2017-12-04 16:00:12 -0500 | [diff] [blame] | 211 | gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_place_audio_call); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 212 | |
| 213 | chat_view_signals[NEW_MESSAGES_DISPLAYED] = g_signal_new ( |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 214 | "new-interactions-displayed", |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 215 | G_TYPE_FROM_CLASS(klass), |
| 216 | (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION), |
| 217 | 0, |
| 218 | nullptr, |
| 219 | nullptr, |
| 220 | g_cclosure_marshal_VOID__VOID, |
| 221 | G_TYPE_NONE, 0); |
Stepan Salenikovich | 8043a56 | 2016-03-18 13:56:40 -0400 | [diff] [blame] | 222 | |
| 223 | chat_view_signals[HIDE_VIEW_CLICKED] = g_signal_new ( |
| 224 | "hide-view-clicked", |
| 225 | G_TYPE_FROM_CLASS(klass), |
| 226 | (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION), |
| 227 | 0, |
| 228 | nullptr, |
| 229 | nullptr, |
| 230 | g_cclosure_marshal_VOID__VOID, |
| 231 | G_TYPE_NONE, 0); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | static void |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 235 | print_interaction_to_buffer(ChatView* self, uint64_t interactionId, const lrc::api::interaction::Info& interaction) |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 236 | { |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 237 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 238 | |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 239 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 240 | if (interaction.status == lrc::api::interaction::Status::UNREAD) |
| 241 | priv->accountContainer_->info.conversationModel->setInteractionRead(priv->conversation_->uid, interactionId); |
| 242 | |
| 243 | webkit_chat_container_print_new_interaction( |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 244 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 245 | interactionId, |
| 246 | interaction |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 247 | ); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 248 | } |
| 249 | |
aviau | fc21355 | 2016-11-01 12:39:39 -0400 | [diff] [blame] | 250 | static void |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 251 | update_interaction(ChatView* self, uint64_t interactionId, const lrc::api::interaction::Info& interaction) |
aviau | fc21355 | 2016-11-01 12:39:39 -0400 | [diff] [blame] | 252 | { |
| 253 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 254 | webkit_chat_container_update_interaction( |
| 255 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 256 | interactionId, |
| 257 | interaction |
aviau | fc21355 | 2016-11-01 12:39:39 -0400 | [diff] [blame] | 258 | ); |
aviau | fc21355 | 2016-11-01 12:39:39 -0400 | [diff] [blame] | 259 | } |
| 260 | |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 261 | static void |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 262 | load_participants_images(ChatView *self) |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 263 | { |
| 264 | g_return_if_fail(IS_CHAT_VIEW(self)); |
| 265 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 266 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 267 | // Contact |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 268 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 269 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 270 | try{ |
| 271 | auto& contact = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 272 | if (!contact.profileInfo.avatar.empty()) { |
| 273 | webkit_chat_container_set_sender_image( |
| 274 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 275 | priv->accountContainer_->info.contactModel->getContactProfileId(contactUri), |
| 276 | contact.profileInfo.avatar |
| 277 | ); |
| 278 | } |
| 279 | } catch (const std::out_of_range&) { |
| 280 | // ContactModel::getContact() exception |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 281 | } |
| 282 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 283 | // For this account |
| 284 | if (!priv->accountContainer_->info.profileInfo.avatar.empty()) { |
| 285 | webkit_chat_container_set_sender_image( |
| 286 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 287 | priv->accountContainer_->info.contactModel->getContactProfileId(priv->accountContainer_->info.profileInfo.uri), |
| 288 | priv->accountContainer_->info.profileInfo.avatar |
| 289 | ); |
| 290 | } |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 291 | } |
| 292 | |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 293 | static void |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 294 | print_text_recording(ChatView *self) |
| 295 | { |
| 296 | g_return_if_fail(IS_CHAT_VIEW(self)); |
| 297 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 298 | |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 299 | if (!priv->conversation_) return; |
Sébastien Blin | 05317a7 | 2018-02-21 11:09:16 -0500 | [diff] [blame] | 300 | webkit_chat_container_print_history( |
| 301 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 302 | priv->conversation_->interactions |
| 303 | ); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 304 | |
| 305 | QObject::disconnect(priv->new_interaction_connection); |
| 306 | } |
| 307 | |
| 308 | static void |
| 309 | update_add_to_conversations(ChatView *self) |
Sébastien Blin | f3681aa | 2017-07-19 16:53:49 -0400 | [diff] [blame] | 310 | { |
| 311 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 312 | |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 313 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 314 | auto participant = priv->conversation_->participants[0]; |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 315 | try { |
| 316 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(participant); |
| 317 | if(contactInfo.profileInfo.type != lrc::api::profile::Type::TEMPORARY |
| 318 | && contactInfo.profileInfo.type != lrc::api::profile::Type::PENDING) |
| 319 | gtk_widget_hide(priv->button_add_to_conversations); |
| 320 | } catch (const std::out_of_range&) { |
| 321 | // ContactModel::getContact() exception |
| 322 | } |
Stepan Salenikovich | 5039c9b | 2016-02-12 14:09:51 -0500 | [diff] [blame] | 323 | } |
| 324 | |
| 325 | static void |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 326 | update_contact_methods(ChatView *self) |
| 327 | { |
| 328 | g_return_if_fail(IS_CHAT_VIEW(self)); |
| 329 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 330 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 331 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 332 | try { |
| 333 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 334 | auto bestId = std::string(contactInfo.registeredName).empty() ? contactInfo.profileInfo.uri : contactInfo.registeredName; |
| 335 | if (contactInfo.profileInfo.alias == bestId) { |
| 336 | gtk_widget_hide(priv->label_cm); |
| 337 | } else { |
| 338 | gtk_label_set_text(GTK_LABEL(priv->label_cm), bestId.c_str()); |
| 339 | gtk_widget_show(priv->label_cm); |
| 340 | } |
| 341 | } catch (const std::out_of_range&) { |
| 342 | // ContactModel::getContact() exception |
AmarOk | cba0395 | 2017-07-17 10:13:49 -0400 | [diff] [blame] | 343 | } |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 344 | } |
| 345 | |
| 346 | static void |
Sébastien Blin | f3681aa | 2017-07-19 16:53:49 -0400 | [diff] [blame] | 347 | update_name(ChatView *self) |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 348 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 349 | g_return_if_fail(IS_CHAT_VIEW(self)); |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 350 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 351 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 352 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 353 | try { |
| 354 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 355 | auto alias = contactInfo.profileInfo.alias; |
| 356 | alias.erase(std::remove(alias.begin(), alias.end(), '\r'), alias.end()); |
| 357 | gtk_label_set_text(GTK_LABEL(priv->label_peer), alias.c_str()); |
| 358 | } catch (const std::out_of_range&) { |
| 359 | // ContactModel::getContact() exception |
| 360 | } |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 361 | } |
| 362 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 363 | static void |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 364 | webkit_chat_container_ready(ChatView* self) |
| 365 | { |
| 366 | /* The webkit chat container has loaded the javascript libraries, we can |
| 367 | * now use it. */ |
| 368 | |
| 369 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 370 | |
| 371 | webkit_chat_container_clear( |
| 372 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container) |
| 373 | ); |
| 374 | |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 375 | display_links_toggled(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 376 | print_text_recording(self); |
| 377 | load_participants_images(self); |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 378 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 379 | priv->new_interaction_connection = QObject::connect( |
Nicolas Jager | 6635b0d | 2018-01-24 12:25:28 -0500 | [diff] [blame] | 380 | &*priv->accountContainer_->info.conversationModel, &lrc::api::ConversationModel::newInteraction, |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 381 | [self, priv](const std::string& uid, uint64_t interactionId, lrc::api::interaction::Info interaction) { |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 382 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 383 | if(uid == priv->conversation_->uid) { |
| 384 | print_interaction_to_buffer(self, interactionId, interaction); |
| 385 | } |
| 386 | }); |
| 387 | |
| 388 | priv->update_interaction_connection = QObject::connect( |
| 389 | &*priv->accountContainer_->info.conversationModel, &lrc::api::ConversationModel::interactionStatusUpdated, |
| 390 | [self, priv](const std::string& uid, uint64_t msgId, lrc::api::interaction::Info msg) { |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 391 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 392 | if(uid == priv->conversation_->uid) { |
| 393 | update_interaction(self, msgId, msg); |
| 394 | } |
| 395 | }); |
| 396 | |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 397 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 398 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 399 | try { |
| 400 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 401 | priv->isTemporary_ = contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY |
| 402 | || contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING; |
| 403 | webkit_chat_container_set_temporary(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), priv->isTemporary_); |
| 404 | auto bestName = contactInfo.profileInfo.alias; |
| 405 | if (bestName.empty()) |
| 406 | bestName = contactInfo.registeredName; |
| 407 | if (bestName.empty()) |
| 408 | bestName = contactInfo.profileInfo.uri; |
| 409 | bestName.erase(std::remove(bestName.begin(), bestName.end(), '\r'), bestName.end()); |
| 410 | webkit_chat_container_set_invitation(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 411 | (contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING), |
| 412 | bestName); |
| 413 | webkit_chat_disable_send_interaction(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 414 | (contactInfo.profileInfo.type == lrc::api::profile::Type::SIP) |
| 415 | && priv->conversation_->callId.empty()); |
| 416 | } catch (const std::out_of_range&) { |
| 417 | // ContactModel::getContact() exception |
| 418 | } |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 419 | } |
| 420 | |
| 421 | static void |
| 422 | build_chat_view(ChatView* self) |
| 423 | { |
| 424 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 425 | |
| 426 | gtk_container_add(GTK_CONTAINER(priv->box_webkit_chat_container), priv->webkit_chat_container); |
| 427 | gtk_widget_show(priv->webkit_chat_container); |
| 428 | |
Sébastien Blin | f3681aa | 2017-07-19 16:53:49 -0400 | [diff] [blame] | 429 | update_name(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 430 | update_add_to_conversations(self); |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 431 | update_contact_methods(self); |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 432 | |
| 433 | priv->webkit_ready = g_signal_connect_swapped( |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 434 | priv->webkit_chat_container, |
| 435 | "ready", |
| 436 | G_CALLBACK(webkit_chat_container_ready), |
| 437 | self |
| 438 | ); |
| 439 | |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 440 | priv->webkit_send_text = g_signal_connect(priv->webkit_chat_container, |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 441 | "script-dialog", |
| 442 | G_CALLBACK(webkit_chat_container_script_dialog), |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 443 | self); |
| 444 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 445 | if (webkit_chat_container_is_ready(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container))) |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 446 | webkit_chat_container_ready(self); |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 447 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 448 | gtk_widget_set_visible(priv->hbox_chat_info, TRUE); |
| 449 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 450 | } |
| 451 | |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 452 | GtkWidget * |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 453 | chat_view_new (WebKitChatContainer* webkit_chat_container, |
| 454 | AccountContainer* accountContainer, |
| 455 | lrc::api::conversation::Info* conversation) |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 456 | { |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 457 | ChatView *self = CHAT_VIEW(g_object_new(CHAT_VIEW_TYPE, NULL)); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 458 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 459 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 460 | priv->webkit_chat_container = GTK_WIDGET(webkit_chat_container); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 461 | priv->conversation_ = conversation; |
| 462 | priv->accountContainer_ = accountContainer; |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 463 | |
| 464 | build_chat_view(self); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 465 | return (GtkWidget *)self; |
| 466 | } |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 467 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 468 | void |
| 469 | chat_view_update_temporary(ChatView* self, bool newValue) |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 470 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 471 | g_return_if_fail(IS_CHAT_VIEW(self)); |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 472 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
| 473 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 474 | priv->isTemporary_ = newValue; |
| 475 | if (!priv->isTemporary_) { |
| 476 | gtk_widget_hide(priv->button_add_to_conversations); |
| 477 | } |
| 478 | webkit_chat_container_set_temporary(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), priv->isTemporary_); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 479 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 480 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 481 | try { |
| 482 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 483 | auto bestName = contactInfo.profileInfo.alias; |
| 484 | if (bestName.empty()) |
| 485 | bestName = contactInfo.registeredName; |
| 486 | if (bestName.empty()) |
| 487 | bestName = contactInfo.profileInfo.uri; |
| 488 | webkit_chat_container_set_invitation(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 489 | newValue, |
| 490 | bestName); |
| 491 | } catch (const std::out_of_range&) { |
| 492 | // ContactModel::getContact() exception |
| 493 | } |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 494 | } |
| 495 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 496 | bool |
| 497 | chat_view_get_temporary(ChatView *self) |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 498 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 499 | g_return_val_if_fail(IS_CHAT_VIEW(self), false); |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 500 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 501 | return priv->isTemporary_; |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 502 | } |
| 503 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 504 | lrc::api::conversation::Info |
| 505 | chat_view_get_conversation(ChatView *self) |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 506 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 507 | g_return_val_if_fail(IS_CHAT_VIEW(self), lrc::api::conversation::Info()); |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 508 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 509 | return *priv->conversation_; |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 510 | } |
Stepan Salenikovich | daf3cb3 | 2016-10-12 16:39:42 -0400 | [diff] [blame] | 511 | |
| 512 | void |
| 513 | chat_view_set_header_visible(ChatView *self, gboolean visible) |
| 514 | { |
| 515 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Stepan Salenikovich | daf3cb3 | 2016-10-12 16:39:42 -0400 | [diff] [blame] | 516 | gtk_widget_set_visible(priv->hbox_chat_info, visible); |
| 517 | } |