Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 1 | /* |
Guillaume Roguez | 2a6150d | 2017-07-19 18:24:47 -0400 | [diff] [blame] | 2 | * Copyright (C) 2016-2017 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 | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 300 | for (const auto& interaction : priv->conversation_->interactions) |
| 301 | print_interaction_to_buffer(self, interaction.first, interaction.second); |
| 302 | |
| 303 | QObject::disconnect(priv->new_interaction_connection); |
| 304 | } |
| 305 | |
| 306 | static void |
| 307 | update_add_to_conversations(ChatView *self) |
Sébastien Blin | f3681aa | 2017-07-19 16:53:49 -0400 | [diff] [blame] | 308 | { |
| 309 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 310 | |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 311 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 312 | auto participant = priv->conversation_->participants[0]; |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 313 | try { |
| 314 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(participant); |
| 315 | if(contactInfo.profileInfo.type != lrc::api::profile::Type::TEMPORARY |
| 316 | && contactInfo.profileInfo.type != lrc::api::profile::Type::PENDING) |
| 317 | gtk_widget_hide(priv->button_add_to_conversations); |
| 318 | } catch (const std::out_of_range&) { |
| 319 | // ContactModel::getContact() exception |
| 320 | } |
Stepan Salenikovich | 5039c9b | 2016-02-12 14:09:51 -0500 | [diff] [blame] | 321 | } |
| 322 | |
| 323 | static void |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 324 | update_contact_methods(ChatView *self) |
| 325 | { |
| 326 | g_return_if_fail(IS_CHAT_VIEW(self)); |
| 327 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 328 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 329 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 330 | try { |
| 331 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 332 | auto bestId = std::string(contactInfo.registeredName).empty() ? contactInfo.profileInfo.uri : contactInfo.registeredName; |
| 333 | if (contactInfo.profileInfo.alias == bestId) { |
| 334 | gtk_widget_hide(priv->label_cm); |
| 335 | } else { |
| 336 | gtk_label_set_text(GTK_LABEL(priv->label_cm), bestId.c_str()); |
| 337 | gtk_widget_show(priv->label_cm); |
| 338 | } |
| 339 | } catch (const std::out_of_range&) { |
| 340 | // ContactModel::getContact() exception |
AmarOk | cba0395 | 2017-07-17 10:13:49 -0400 | [diff] [blame] | 341 | } |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 342 | } |
| 343 | |
| 344 | static void |
Sébastien Blin | f3681aa | 2017-07-19 16:53:49 -0400 | [diff] [blame] | 345 | update_name(ChatView *self) |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 346 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 347 | g_return_if_fail(IS_CHAT_VIEW(self)); |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 348 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 349 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 350 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 351 | try { |
| 352 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 353 | auto alias = contactInfo.profileInfo.alias; |
| 354 | alias.erase(std::remove(alias.begin(), alias.end(), '\r'), alias.end()); |
| 355 | gtk_label_set_text(GTK_LABEL(priv->label_peer), alias.c_str()); |
| 356 | } catch (const std::out_of_range&) { |
| 357 | // ContactModel::getContact() exception |
| 358 | } |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 359 | } |
| 360 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 361 | static void |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 362 | webkit_chat_container_ready(ChatView* self) |
| 363 | { |
| 364 | /* The webkit chat container has loaded the javascript libraries, we can |
| 365 | * now use it. */ |
| 366 | |
| 367 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 368 | |
| 369 | webkit_chat_container_clear( |
| 370 | WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container) |
| 371 | ); |
| 372 | |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 373 | display_links_toggled(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 374 | print_text_recording(self); |
| 375 | load_participants_images(self); |
Sébastien Blin | 70dc0b7 | 2017-07-31 16:24:41 -0400 | [diff] [blame] | 376 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 377 | priv->new_interaction_connection = QObject::connect( |
Nicolas Jager | 6635b0d | 2018-01-24 12:25:28 -0500 | [diff] [blame^] | 378 | &*priv->accountContainer_->info.conversationModel, &lrc::api::ConversationModel::newInteraction, |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 379 | [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] | 380 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 381 | if(uid == priv->conversation_->uid) { |
| 382 | print_interaction_to_buffer(self, interactionId, interaction); |
| 383 | } |
| 384 | }); |
| 385 | |
| 386 | priv->update_interaction_connection = QObject::connect( |
| 387 | &*priv->accountContainer_->info.conversationModel, &lrc::api::ConversationModel::interactionStatusUpdated, |
| 388 | [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] | 389 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 390 | if(uid == priv->conversation_->uid) { |
| 391 | update_interaction(self, msgId, msg); |
| 392 | } |
| 393 | }); |
| 394 | |
Sébastien Blin | 5851aaf | 2017-11-06 16:02:08 -0500 | [diff] [blame] | 395 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 396 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 397 | try { |
| 398 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 399 | priv->isTemporary_ = contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY |
| 400 | || contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING; |
| 401 | webkit_chat_container_set_temporary(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), priv->isTemporary_); |
| 402 | auto bestName = contactInfo.profileInfo.alias; |
| 403 | if (bestName.empty()) |
| 404 | bestName = contactInfo.registeredName; |
| 405 | if (bestName.empty()) |
| 406 | bestName = contactInfo.profileInfo.uri; |
| 407 | bestName.erase(std::remove(bestName.begin(), bestName.end(), '\r'), bestName.end()); |
| 408 | webkit_chat_container_set_invitation(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 409 | (contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING), |
| 410 | bestName); |
| 411 | webkit_chat_disable_send_interaction(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 412 | (contactInfo.profileInfo.type == lrc::api::profile::Type::SIP) |
| 413 | && priv->conversation_->callId.empty()); |
| 414 | } catch (const std::out_of_range&) { |
| 415 | // ContactModel::getContact() exception |
| 416 | } |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 417 | } |
| 418 | |
| 419 | static void |
| 420 | build_chat_view(ChatView* self) |
| 421 | { |
| 422 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 423 | |
| 424 | gtk_container_add(GTK_CONTAINER(priv->box_webkit_chat_container), priv->webkit_chat_container); |
| 425 | gtk_widget_show(priv->webkit_chat_container); |
| 426 | |
Sébastien Blin | f3681aa | 2017-07-19 16:53:49 -0400 | [diff] [blame] | 427 | update_name(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 428 | update_add_to_conversations(self); |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 429 | update_contact_methods(self); |
Stepan Salenikovich | 1f73121 | 2016-11-10 11:55:10 -0500 | [diff] [blame] | 430 | |
| 431 | priv->webkit_ready = g_signal_connect_swapped( |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 432 | priv->webkit_chat_container, |
| 433 | "ready", |
| 434 | G_CALLBACK(webkit_chat_container_ready), |
| 435 | self |
| 436 | ); |
| 437 | |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 438 | priv->webkit_send_text = g_signal_connect(priv->webkit_chat_container, |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 439 | "script-dialog", |
| 440 | G_CALLBACK(webkit_chat_container_script_dialog), |
AmarOk | b425324 | 2017-07-13 11:21:39 -0400 | [diff] [blame] | 441 | self); |
| 442 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 443 | if (webkit_chat_container_is_ready(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container))) |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 444 | webkit_chat_container_ready(self); |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 445 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 446 | gtk_widget_set_visible(priv->hbox_chat_info, TRUE); |
| 447 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 448 | } |
| 449 | |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 450 | GtkWidget * |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 451 | chat_view_new (WebKitChatContainer* webkit_chat_container, |
| 452 | AccountContainer* accountContainer, |
| 453 | lrc::api::conversation::Info* conversation) |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 454 | { |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 455 | ChatView *self = CHAT_VIEW(g_object_new(CHAT_VIEW_TYPE, NULL)); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 456 | |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 457 | ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self); |
| 458 | priv->webkit_chat_container = GTK_WIDGET(webkit_chat_container); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 459 | priv->conversation_ = conversation; |
| 460 | priv->accountContainer_ = accountContainer; |
aviau | 039001d | 2016-09-29 16:39:05 -0400 | [diff] [blame] | 461 | |
| 462 | build_chat_view(self); |
Stepan Salenikovich | d2cad06 | 2016-01-08 13:43:49 -0500 | [diff] [blame] | 463 | return (GtkWidget *)self; |
| 464 | } |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 465 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 466 | void |
| 467 | chat_view_update_temporary(ChatView* self, bool newValue) |
Stepan Salenikovich | c6a3b98 | 2016-01-11 18:11:39 -0500 | [diff] [blame] | 468 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 469 | g_return_if_fail(IS_CHAT_VIEW(self)); |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 470 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
| 471 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 472 | priv->isTemporary_ = newValue; |
| 473 | if (!priv->isTemporary_) { |
| 474 | gtk_widget_hide(priv->button_add_to_conversations); |
| 475 | } |
| 476 | 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] | 477 | if (!priv->conversation_) return; |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 478 | auto contactUri = priv->conversation_->participants.front(); |
Guillaume Roguez | c209592 | 2017-12-14 14:07:10 -0500 | [diff] [blame] | 479 | try { |
| 480 | auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri); |
| 481 | auto bestName = contactInfo.profileInfo.alias; |
| 482 | if (bestName.empty()) |
| 483 | bestName = contactInfo.registeredName; |
| 484 | if (bestName.empty()) |
| 485 | bestName = contactInfo.profileInfo.uri; |
| 486 | webkit_chat_container_set_invitation(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), |
| 487 | newValue, |
| 488 | bestName); |
| 489 | } catch (const std::out_of_range&) { |
| 490 | // ContactModel::getContact() exception |
| 491 | } |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 492 | } |
| 493 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 494 | bool |
| 495 | chat_view_get_temporary(ChatView *self) |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 496 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 497 | g_return_val_if_fail(IS_CHAT_VIEW(self), false); |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 498 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 499 | return priv->isTemporary_; |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 500 | } |
| 501 | |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 502 | lrc::api::conversation::Info |
| 503 | chat_view_get_conversation(ChatView *self) |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 504 | { |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 505 | 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] | 506 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Sébastien Blin | 55bff9d | 2017-10-03 15:15:23 -0400 | [diff] [blame] | 507 | return *priv->conversation_; |
Stepan Salenikovich | 09e0b78 | 2016-09-07 16:28:50 -0400 | [diff] [blame] | 508 | } |
Stepan Salenikovich | daf3cb3 | 2016-10-12 16:39:42 -0400 | [diff] [blame] | 509 | |
| 510 | void |
| 511 | chat_view_set_header_visible(ChatView *self, gboolean visible) |
| 512 | { |
| 513 | auto priv = CHAT_VIEW_GET_PRIVATE(self); |
Stepan Salenikovich | daf3cb3 | 2016-10-12 16:39:42 -0400 | [diff] [blame] | 514 | gtk_widget_set_visible(priv->hbox_chat_info, visible); |
| 515 | } |