blob: 65285938d3d4be28ec5736958bc3f67b7b8209cb [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04002 * Copyright (C) 2015-2018 by Savoir-faire Linux *
Edric Milaret627500d2015-03-27 16:41:40 -04003 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -04004 * Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com> *
5 * Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com> *
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04006 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> *
Isa Nanic37ccc1c2018-10-26 14:16:28 -04007 * Author: Isa Nanic <isa.nanic@savoirfairelinux.com> *
Edric Milaret627500d2015-03-27 16:41:40 -04008 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 3 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
21 **************************************************************************/
22
23#include "callwidget.h"
24#include "ui_callwidget.h"
25
Andreas Traczyk912242e2018-10-29 14:44:44 -040026#include <QScrollBar>
Edric Milaret43f3c1e2015-07-16 17:52:47 -040027#include <QClipboard>
Edric Milaret70ae8782016-04-18 16:10:44 -040028#include <QDesktopServices>
Isa Nanic601de1d2018-10-23 11:37:26 -040029#include <QComboBox>
Andreas Traczyk43c08232018-10-31 13:42:09 -040030#include <QWebEngineScript>
Edric Milaret43f3c1e2015-07-16 17:52:47 -040031
Sébastien Blin942d1022018-12-13 09:49:03 -050032#include <algorithm>
Edric Milaret53f57b62015-05-11 11:02:17 -040033#include <memory>
Edric Milaret627500d2015-03-27 16:41:40 -040034
Edric Milarete19c4cd2016-02-12 10:19:44 -050035#include "qrencode.h"
36
Edric Milaret43f3c1e2015-07-16 17:52:47 -040037//ERROR is defined in windows.h
38#include "utils.h"
39#undef ERROR
Edric Milareta0ebd062016-01-13 12:18:23 -050040#undef interface
Edric Milaret43f3c1e2015-07-16 17:52:47 -040041
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040042// lrc
Edric Milareta0ebd062016-01-13 12:18:23 -050043#include "globalinstances.h"
Olivier SOLDANO69361192017-04-20 10:32:05 -040044#include "profilemodel.h"
Olivier SOLDANO69361192017-04-20 10:32:05 -040045#include "localprofilecollection.h"
Anthony Léonardd47179c2017-03-28 10:39:10 -040046
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040047// client
Edric Milaret559bda52015-04-29 17:02:31 -040048#include "wizarddialog.h"
Edric Milaret83b248c2015-06-02 11:42:23 -040049#include "windowscontactbackend.h"
Edric Milaret2cf34292015-06-22 16:27:03 -040050#include "globalsystemtray.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040051#include "conversationitemdelegate.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050052#include "pixbufmanipulator.h"
Edric Milaret70ae8782016-04-18 16:10:44 -040053#include "settingskey.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040054#include "lrcinstance.h"
Andreas Traczyk43c08232018-10-31 13:42:09 -040055#include "animationhelpers.h"
56#include "ringthemeutils.h"
Edric Milaret25236d92016-03-28 09:40:58 -040057
Nicolas Jager97a21b42015-12-03 16:55:45 -050058CallWidget::CallWidget(QWidget* parent) :
Nicolas Jager74fe46f2016-02-29 14:55:09 -050059 NavWidget(parent),
Edric Milaret7d40a4a2015-05-13 13:01:15 -040060 ui(new Ui::CallWidget),
Andreas Traczyk43c08232018-10-31 13:42:09 -040061 menu_(new QMenu())
Edric Milaret627500d2015-03-27 16:41:40 -040062{
63 ui->setupUi(this);
64
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040065 using namespace lrc::api;
Nicolas Jagerca850292016-01-17 14:11:10 -050066
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040067 QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
Edric Milaret3aca8e32015-06-12 10:01:40 -040068
Sébastien Blincba5b522018-12-10 12:48:36 -050069 QPixmap logo(":/images/logo-jami-standard-coul.png");
Edric Milareted0b2802015-10-01 15:10:02 -040070 ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
71 ui->ringLogo->setAlignment(Qt::AlignHCenter);
72
Edric Milaret1e598592016-09-02 10:10:01 -040073 ui->qrLabel->hide();
Edric Milarete19c4cd2016-02-12 10:19:44 -050074
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040075 videoRenderer_ = nullptr;
Edric Milaret627500d2015-03-27 16:41:40 -040076
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040077 // this line is not welcome here, and must be removed
78 ProfileModel::instance().addCollection<LocalProfileCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -040079
Andreas Traczyk43c08232018-10-31 13:42:09 -040080 QSettings settings;
81
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040082 // select last used account if stored in registry
83 auto accountList = LRCInstance::accountModel().getAccountList();
84 if (!accountList.empty()) {
85 std::string accountIdToStartWith;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040086 if (settings.contains(SettingsKey::selectedAccount)) {
87 accountIdToStartWith = settings
88 .value(SettingsKey::selectedAccount, true)
89 .value<QString>()
90 .toStdString();
91 if (Utils::indexInVector(accountList, accountIdToStartWith) == -1) {
92 accountIdToStartWith = accountList.at(0);
Olivier SOLDANOaf8f2822017-07-11 12:15:18 -040093 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040094 }
95 else {
96 accountIdToStartWith = accountList.at(0);
97 }
98 setSelectedAccount(accountIdToStartWith);
Isa Nanic601de1d2018-10-23 11:37:26 -040099 // get account index and set the currentAccountComboBox
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400100 auto index = Utils::indexInVector(accountList, accountIdToStartWith);
101 if (index != -1) {
Isa Nanic601de1d2018-10-23 11:37:26 -0400102 ui->currentAccountComboBox->setCurrentIndex(index);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400103 }
Edric Milaret627500d2015-03-27 16:41:40 -0400104 }
Olivier SOLDANO2100f1c2017-09-06 16:45:20 -0400105
Andreas Traczyk43c08232018-10-31 13:42:09 -0400106 if (settings.contains(SettingsKey::mainSplitterState)) {
107 auto splitterStates = settings.value(SettingsKey::mainSplitterState).toByteArray();
108 ui->mainActivitySplitter->restoreState(splitterStates);
109 }
110
111 ui->mainActivitySplitter->setCollapsible(0, false);
Sébastien Blin93bd2062018-12-17 15:57:16 -0500112 ui->mainActivitySplitter->setCollapsible(1, false);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400113 ui->splitter->setCollapsible(0, false);
114 ui->splitter->setCollapsible(1, false);
115
Isa Nanic601de1d2018-10-23 11:37:26 -0400116 //disable dropdown shadow on combobox
117 ui->currentAccountComboBox->view()->window()->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
118
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400119 // conversation list
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400120 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
121
122 // setup searchingfor mini spinner
123 miniSpinner_ = new QMovie(":/images/waiting.gif");
124 ui->spinnerLabel->setMovie(miniSpinner_);
125 ui->spinnerLabel->hide();
126
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400127 // connections
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400128 connect(ui->currentAccountComboBox, &CurrentAccountComboBox::settingsButtonClicked,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400129 this, &CallWidget::settingsButtonClicked);
130
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500131 connect(ui->currentAccountComboBox, &CurrentAccountComboBox::newAccountClicked,
132 [this]() {
133 emit NavigationRequested(ScreenEnum::WizardScreen);
134 });
135
Andreas Traczyk43c08232018-10-31 13:42:09 -0400136 connect(ui->videoWidget, &VideoView::setChatVisibility,
137 [this](bool visible) {
Sébastien Blin93bd2062018-12-17 15:57:16 -0500138 if (visible) {
139 ui->messagesWidget->show();
140 } else {
141 ui->messagesWidget->hide();
142 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400143 });
144
145 connect(ui->mainActivitySplitter, &QSplitter::splitterMoved,
146 [this](int pos, int index) {
Andreas Traczyk14c3e862018-12-26 14:02:30 -0500147 Q_UNUSED(index);
148 Q_UNUSED(pos);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400149 QSettings settings;
150 settings.setValue(SettingsKey::mainSplitterState, ui->mainActivitySplitter->saveState());
151 });
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400152
153 connect(ui->videoWidget, &VideoView::videoSettingsClicked,
154 this, &CallWidget::settingsButtonClicked);
155
Sébastien Blin62b08ac2018-12-14 16:18:04 -0500156 connect(ui->videoWidget, &VideoView::toggleFullScreenClicked,
157 this, &CallWidget::slotToggleFullScreenClicked);
158
159 connect(ui->videoWidget, &VideoView::closing,
160 this, &CallWidget::slotVideoViewDestroyed);
161
Andreas Traczyk43c08232018-10-31 13:42:09 -0400162 connect(ui->btnConversations, &QPushButton::clicked,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400163 this, &CallWidget::conversationsButtonClicked);
164
Andreas Traczyk43c08232018-10-31 13:42:09 -0400165 connect(ui->btnInvites, &QPushButton::clicked,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400166 this, &CallWidget::invitationsButtonClicked);
167
Andreas Traczyk43c08232018-10-31 13:42:09 -0400168 connect(ui->smartList, &QTreeView::customContextMenuRequested,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400169 this, &CallWidget::slotCustomContextMenuRequested);
170
171 connect(ui->smartList, &SmartListView::btnAcceptInviteClicked,
172 this, &CallWidget::slotAcceptInviteClicked);
173
174 connect(ui->smartList, &SmartListView::btnBlockInviteClicked,
175 this, &CallWidget::slotBlockInviteClicked);
176
177 connect(ui->smartList, &SmartListView::btnIgnoreInviteClicked,
178 this, &CallWidget::slotIgnoreInviteClicked);
179
180 connect(&LRCInstance::behaviorController(), &BehaviorController::showCallView,
181 this, &CallWidget::slotShowCallView);
182
183 connect(&LRCInstance::behaviorController(), &BehaviorController::showIncomingCallView,
184 this, &CallWidget::slotShowIncomingCallView);
185
186 connect(&LRCInstance::behaviorController(), &BehaviorController::showChatView,
187 this, &CallWidget::slotShowChatView);
Andreas Traczyk55f92cb2018-10-23 12:26:25 -0400188
Isa Nanic601de1d2018-10-23 11:37:26 -0400189 connect(ui->currentAccountComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
190 this, &CallWidget::slotAccountChanged);
191
Andreas Traczyk912242e2018-10-29 14:44:44 -0400192 connect(ui->sendContactRequestButton, &QPushButton::clicked,
193 this, &CallWidget::on_sendContactRequestButton_clicked);
194
195 connect(ui->btnAudioCall, &QPushButton::clicked,
196 this, &CallWidget::on_sendContactRequestButton_clicked);
197
198 connect(ui->btnVideoCall, &QPushButton::clicked,
199 this, &CallWidget::on_sendContactRequestButton_clicked);
200
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400201 connect(ui->currentAccountComboBox, QOverload<int>::of(&CurrentAccountComboBox::currentIndexChanged),
202 [this] {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400203 ui->btnConversations->setChecked(true);
204 ui->btnInvites->setChecked(false);
205 });
206
Andreas Traczyk43865372018-12-27 12:12:35 -0500207 connect(ui->messageView, &MessageWebView::conversationRemoved,
208 [this] {
209 backToWelcomePage();
210 });
211
Andreas Traczyk55f92cb2018-10-23 12:26:25 -0400212 // set first view to welcome view
213 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400214 ui->btnConversations->setChecked(true);
215
216 // chat view
217 ui->messageView->buildView();
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500218
Andreas Traczykb81281e2018-12-13 13:13:28 -0500219 // hide the call stack
220 ui->callStackWidget->hide();
Andreas Traczykfc33a492018-12-14 13:53:13 -0500221
222 ui->containerWidget->setVisible(false);
Edric Milaret627500d2015-03-27 16:41:40 -0400223}
224
225CallWidget::~CallWidget()
226{
227 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400228 delete menu_;
Edric Milaret00a32252016-01-19 10:37:13 -0500229}
230
Andreas Traczykfc33a492018-12-14 13:53:13 -0500231void
232CallWidget::navigated(bool to)
233{
234 ui->containerWidget->setVisible(to);
235 if (to) {
236 updateSmartList();
237 connectConversationModel();
Andreas Traczyk3fc824d2019-01-02 15:20:21 -0500238 try {
239 auto accountList = LRCInstance::accountModel().getAccountList();
240 if (accountList.size() == 1) {
241 auto index = Utils::indexInVector(accountList, LRCInstance::getCurrAccId());
242 if (index != -1) {
243 slotAccountChanged(index);
244 }
245 }
246 } catch (...) {}
Andreas Traczykb15c83a2018-12-31 12:29:25 -0500247 ui->currentAccountComboBox->updateComboBoxDisplay();
Andreas Traczykfc33a492018-12-14 13:53:13 -0500248 } else {
249 QObject::disconnect(smartlistSelectionConnection_);
250 smartListModel_.reset(nullptr);
251 }
252}
253
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500254void CallWidget::updateCustomUI()
255{
256}
257
Andreas Traczykb81281e2018-12-13 13:13:28 -0500258int
259CallWidget::getLeftPanelWidth()
260{
261 return ui->currentAccountComboBox->width();
262}
263
Edric Milaret00a32252016-01-19 10:37:13 -0500264void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400265CallWidget::onIncomingMessage(const std::string& convUid,
266 uint64_t interactionId,
267 const lrc::api::interaction::Info& interaction)
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400268{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400269 Q_UNUSED(interactionId);
Edric Milaret00a32252016-01-19 10:37:13 -0500270 if (!QApplication::focusWidget()) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400271 auto convModel = LRCInstance::getCurrentConversationModel();
272 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
273 auto bestName = Utils::bestNameForConversation(*conversation, *convModel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400274 Utils::showSystemNotification(this,
275 QString(tr("Message incoming from %1"))
Andreas Traczyk43c08232018-10-31 13:42:09 -0400276 .arg(QString::fromStdString(bestName)));
Edric Milaret00a32252016-01-19 10:37:13 -0500277 }
Andreas Traczyk1d8159a2018-12-13 15:48:24 -0500278 updateConversationsFilterWidget();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500279 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400280 return;
281 }
282
283 auto convModel = LRCInstance::getCurrentConversationModel();
284 convModel->clearUnreadInteractions(convUid);
285 auto currentConversation = Utils::getConversationFromUid(convUid, *convModel);
286 if (currentConversation == convModel->allFilteredConversations().end()) {
287 return;
288 }
289 ui->messageView->printNewInteraction(*convModel, interactionId, interaction);
Edric Milareta0ebd062016-01-13 12:18:23 -0500290}
291
292void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400293CallWidget::setupSmartListContextMenu(const QPoint& pos)
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400294{
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400295 QPoint globalPos = ui->smartList->mapToGlobal(pos);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400296 auto index = ui->smartList->indexAt(pos);
297 if (not index.isValid()) {
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400298 return;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400299 }
300
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400301 auto convModel = LRCInstance::getCurrentConversationModel();
302 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID))
303 .value<QString>()
304 .toStdString();
305 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
306 auto contactUid = (*conversation).participants.at(0);
307 auto contact = LRCInstance::getCurrentAccountInfo().contactModel.get()->getContact(contactUid);
308
309 if (!Utils::isContactValid(contactUid, *convModel)) {
310 return;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400311 }
312
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400313 QMenu menu;
314
315 // video call
316 auto videoCallAction = new QAction(tr("Start video call"), this);
317 menu.addAction(videoCallAction);
318 connect(videoCallAction, &QAction::triggered,
319 [this, convUid, conversation, convModel]() {
320 convModel->placeCall(convUid);
321 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500322 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400323 selectConversation(*conversation, *convModel);
324 }
325 });
326 // audio call
327 auto audioCallAction = new QAction(tr("Start audio call"), this);
328 menu.addAction(audioCallAction);
329 connect(audioCallAction, &QAction::triggered,
330 [this, convUid, conversation, convModel]() {
331 convModel->placeAudioOnlyCall(convUid);
332 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500333 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400334 selectConversation(*conversation, *convModel);
335 }
336 });
337
338 if (contact.profileInfo.type == lrc::api::profile::Type::RING) {
339 // separator
340 menu.addSeparator();
341
342 // clear conversation
343 auto clearConversationAction = new QAction(tr("Clear conversation"), this);
344 menu.addAction(clearConversationAction);
345 connect(clearConversationAction, &QAction::triggered,
346 [convUid]() {
347 LRCInstance::getCurrentConversationModel()->clearHistory(convUid);
348 });
Sébastien Blin31fccce2018-12-13 11:27:05 -0500349 // remove contact
350 auto removeContactAction = new QAction(tr("Remove contact"), this);
351 menu.addAction(removeContactAction);
352 connect(removeContactAction, &QAction::triggered,
353 [convUid]() {
354 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, false);
355 });
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400356 // block contact
357 auto blockContactAction = new QAction(tr("Block contact"), this);
358 menu.addAction(blockContactAction);
359 connect(blockContactAction, &QAction::triggered,
360 [convUid]() {
361 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, true);
362 });
363
364 // separator
365 menu.addSeparator();
366
367 // copy number(infohash)
368 auto copyNumberAction = new QAction(tr("Copy number"), this);
369 menu.addAction(copyNumberAction);
370 connect(copyNumberAction, &QAction::triggered,
371 [contact]() {
372 QApplication::clipboard()->setText(
373 QString::fromStdString(contact.profileInfo.uri)
374 );
375 });
376 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400377 smartListModel_->isContextMenuOpen = true;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400378 menu.exec(globalPos);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400379 smartListModel_->isContextMenuOpen = false;
Edric Milareta0ebd062016-01-13 12:18:23 -0500380}
381
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400382void
383CallWidget::setupQRCode(QString ringID)
Edric Milarete19c4cd2016-02-12 10:19:44 -0500384{
Anthony Léonarda86a8972016-12-15 10:33:47 -0500385 auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
Edric Milaret6d0e5312016-04-04 16:30:22 -0400386 0, //Let the version be decided by libqrencode
387 QR_ECLEVEL_L, // Lowest level of error correction
Edric Milarete19c4cd2016-02-12 10:19:44 -0500388 QR_MODE_8, // 8-bit data mode
389 1);
390 if (not rcode) {
391 qWarning() << "Failed to generate QR code: " << strerror(errno);
392 return;
393 }
394
395 auto margin = 5;
396 int qrwidth = rcode->width + margin * 2;
397 QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
398 QPainter painter;
399 painter.begin(&result);
400 painter.setClipRect(QRect(0, 0, qrwidth, qrwidth));
401 painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
402 painter.setBrush(Qt::black);
403 painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
Edric Milaret74474f52016-05-16 13:36:23 -0400404 unsigned char* p;
Edric Milarete19c4cd2016-02-12 10:19:44 -0500405 p = rcode->data;
406 for(int y = 0; y < rcode->width; y++) {
Edric Milaret74474f52016-05-16 13:36:23 -0400407 unsigned char* row = (p + (y * rcode->width));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500408 for(int x = 0; x < rcode->width; x++) {
409 if(*(row + x) & 0x1) {
410 painter.drawRect(margin + x, margin + y, 1, 1);
411 }
412 }
413
414 }
415 painter.end();
416 QRcode_free(rcode);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400417 ui->qrLabel->setPixmap(QPixmap::fromImage(result.scaled(QSize(qrSize_, qrSize_),
418 Qt::KeepAspectRatio)));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500419}
420
Edric Milaret627500d2015-03-27 16:41:40 -0400421void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400422CallWidget::on_smartList_clicked(const QModelIndex& index)
Edric Milaret00d34f22016-05-09 16:30:29 -0400423{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400424 Q_UNUSED(index);
Edric Milaret627500d2015-03-27 16:41:40 -0400425}
426
427void
428CallWidget::on_acceptButton_clicked()
429{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400430 auto convModel = LRCInstance::getCurrentConversationModel();
431 auto callModel = LRCInstance::getCurrentCallModel();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500432 auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400433 callModel->accept(conversation->callId);
Edric Milaret627500d2015-03-27 16:41:40 -0400434}
435
436void
437CallWidget::on_refuseButton_clicked()
438{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400439 auto convModel = LRCInstance::getCurrentConversationModel();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500440 auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400441 LRCInstance::getCurrentCallModel()->hangUp(conversation->callId);
442 showConversationView();
Edric Milaret6456baa2015-05-21 12:18:07 -0400443}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400444
445void
Edric Milareted0b2802015-10-01 15:10:02 -0400446CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400447{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400448 auto convModel = LRCInstance::getCurrentConversationModel();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500449 auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400450 LRCInstance::getCurrentCallModel()->hangUp(conversation->callId);
451 showConversationView();
Edric Milaretd8528fa2015-07-07 14:13:51 -0400452}
Edric Milareted0b2802015-10-01 15:10:02 -0400453
454void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400455CallWidget::showConversationView()
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400456{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400457 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
458 ui->messageView->setFocus();
Sébastien Blin93bd2062018-12-17 15:57:16 -0500459 if (ui->messagesWidget->isHidden()) {
460 ui->messagesWidget->show();
461 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400462}
463
464void
465CallWidget::selectSmartlistItem(const std::string & convUid)
466{
467 if (convUid.empty()) {
468 return;
469 }
470 ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect);
471 auto convModel = LRCInstance::getCurrentConversationModel();
472 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
473 if (conversation == convModel->allFilteredConversations().end()) {
474 return;
475 }
476 auto contactURI = QString::fromStdString((*conversation).participants[0]);
477 if (contactURI.isEmpty() ||
478 convModel->owner.contactModel->getContact(contactURI.toStdString()).profileInfo.type == lrc::api::profile::Type::TEMPORARY) {
479 return;
480 }
481 for (int row = 0; row < smartListModel_->rowCount(); row++) {
482 QModelIndex index = smartListModel_->index(row);
483 auto indexContactURI = index.data(SmartListModel::Role::URI).value<QString>();
484 if (indexContactURI == contactURI) {
485 ui->smartList->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
486 return;
487 }
488 }
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400489}
490
491void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500492CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400493{
Olivier SOLDANO70279d32017-07-18 15:21:34 -0400494 if (!index.isValid())
495 return;
496
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500497 LRCInstance::getCurrentConversationModel()->placeCall(LRCInstance::getSelectedConvUid());
Edric Milareted0b2802015-10-01 15:10:02 -0400498
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500499 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(LRCInstance::getSelectedConvUid())));
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400500}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500501
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400502QImage
503CallWidget::imageForConv(const std::string& convUid)
504{
505 return Utils::conversationPhoto(convUid, LRCInstance::getCurrentAccountInfo());
506}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500507
Edric Milareted0b2802015-10-01 15:10:02 -0400508void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400509CallWidget::smartListSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500510{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400511 Q_UNUSED(deselected);
512 QModelIndexList indices = selected.indexes();
513
514 if (indices.isEmpty()) {
Edric Milareted0b2802015-10-01 15:10:02 -0400515 return;
Anthony Léonardecfe7422017-05-04 14:14:37 -0400516 }
Edric Milareted0b2802015-10-01 15:10:02 -0400517
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400518 auto selectedIndex = indices.at(0);
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500519
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400520 if (not selectedIndex.isValid()) {
521 return;
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400522 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400523
524 selectConversation(selectedIndex);
Edric Milareted0b2802015-10-01 15:10:02 -0400525}
526
527void
528CallWidget::placeCall()
529{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500530 if (ui->ringContactLineEdit->text().isEmpty())
Edric Milareted0b2802015-10-01 15:10:02 -0400531 return;
Nicolas Jager97a21b42015-12-03 16:55:45 -0500532 Call* c = CallModel::instance().dialingCall(PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text()));
Edric Milareted0b2802015-10-01 15:10:02 -0400533 c->performAction(Call::Action::ACCEPT);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500534 ui->ringContactLineEdit->clear();
Andreas Traczyk43c08232018-10-31 13:42:09 -0400535 auto photoRect = ui->callingPhoto->frameGeometry();
Edric1bed3f92016-05-19 10:24:48 -0400536 ui->callingPhoto->setPixmap(
537 QPixmap::fromImage(
538 GlobalInstances::pixmapManipulator()
Andreas Traczyk43c08232018-10-31 13:42:09 -0400539 .callPhoto(c, QSize(photoRect.width(), photoRect.height()))
540 .value<QImage>()));
Edric Milareted0b2802015-10-01 15:10:02 -0400541}
542
543void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400544CallWidget::conversationsButtonClicked()
545{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400546 ui->btnConversations->setChecked(true);
547 ui->btnInvites->setChecked(false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400548 setConversationFilter(lrc::api::profile::Type::RING);
549}
550
551void
552CallWidget::invitationsButtonClicked()
553{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400554 ui->btnConversations->setChecked(false);
555 ui->btnInvites->setChecked(true);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400556 setConversationFilter(lrc::api::profile::Type::PENDING);
557}
558
559void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500560CallWidget::settingsButtonClicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400561{
Andreas Traczyk7548e732018-12-12 10:47:21 -0500562 emit NavigationRequested(ScreenEnum::SetttingsScreen);
Edric Milareted0b2802015-10-01 15:10:02 -0400563}
564
565void
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400566CallWidget::processContactLineEdit()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500567{
Anthony Léonardaa90e1a2016-10-12 11:24:17 -0400568 auto contactLineText = ui->ringContactLineEdit->text();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400569 setConversationFilter(contactLineText);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500570}
571
572void
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400573CallWidget::on_ringContactLineEdit_returnPressed()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500574{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400575 // select current temporary item and show conversation
576 auto convModel = LRCInstance::getCurrentConversationModel();
577 auto conversations = convModel->allFilteredConversations();
Andreas Traczyk43c08232018-10-31 13:42:09 -0400578 if (!conversations.empty() &&
579 Utils::isContactValid(conversations.at(0).participants.at(0), *convModel)) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400580 selectConversation(smartListModel_->index(0));
581 }
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400582}
583
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400584void CallWidget::slotAcceptInviteClicked(const QModelIndex & index)
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400585{
Andreas Traczyk43865372018-12-27 12:12:35 -0500586 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
587 LRCInstance::getCurrentConversationModel()->makePermanent(convUid);
588 ui->messageView->setInvitation(false);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500589}
590
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400591void CallWidget::slotBlockInviteClicked(const QModelIndex & index)
Nicolas Jager97a21b42015-12-03 16:55:45 -0500592{
Andreas Traczyk43865372018-12-27 12:12:35 -0500593 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
594 if (!convUid.empty() && convUid == LRCInstance::getSelectedConvUid()) {
595 backToWelcomePage();
596 }
597 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, true);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400598}
599
600void CallWidget::slotIgnoreInviteClicked(const QModelIndex & index)
601{
Andreas Traczyk43865372018-12-27 12:12:35 -0500602 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
603 if (!convUid.empty() && convUid == LRCInstance::getSelectedConvUid()) {
604 backToWelcomePage();
605 }
606 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400607}
608
609void CallWidget::slotCustomContextMenuRequested(const QPoint& pos)
610{
611 setupSmartListContextMenu(pos);
612}
613
Isa Nanic601de1d2018-10-23 11:37:26 -0400614void CallWidget::slotAccountChanged(int index)
615{
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500616 try {
617 auto accountList = LRCInstance::accountModel().getAccountList();
618 setSelectedAccount(accountList.at(index));
619 } catch (...) {
Andreas Traczyk43865372018-12-27 12:12:35 -0500620 qWarning() << "CallWidget::slotAccountChanged exception";
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500621 }
Isa Nanic601de1d2018-10-23 11:37:26 -0400622}
623
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400624void CallWidget::slotShowCallView(const std::string& accountId,
625 const lrc::api::conversation::Info& convInfo)
626{
627 Q_UNUSED(accountId);
628 Q_UNUSED(convInfo);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400629 qDebug() << "slotShowCallView";
630 ui->callStackWidget->show();
631 ui->callStackWidget->setCurrentWidget(ui->videoPage);
Sébastien Blin93bd2062018-12-17 15:57:16 -0500632 ui->videoWidget->showChatviewIfToggled();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400633 hideMiniSpinner();
634}
635
636void CallWidget::slotShowIncomingCallView(const std::string& accountId,
Andreas Traczyk43c08232018-10-31 13:42:09 -0400637 const lrc::api::conversation::Info& convInfo)
638{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400639 Q_UNUSED(accountId);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400640 qDebug() << "slotShowIncomingCallView";
641
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400642 auto callModel = LRCInstance::getCurrentCallModel();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400643
644 if (!callModel->hasCall(convInfo.callId)) {
Nicolas Jager97a21b42015-12-03 16:55:45 -0500645 return;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400646 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500647
Andreas Traczyk43c08232018-10-31 13:42:09 -0400648 auto convModel = LRCInstance::getCurrentConversationModel();
649 ui->callerPhoto->setPixmap(QPixmap::fromImage(imageForConv(convInfo.uid)));
650 auto bestName = QString::fromStdString(Utils::bestNameForConversation(convInfo, *convModel));
651 auto bestId = QString::fromStdString(Utils::bestIdForConversation(convInfo, *convModel));
652 auto finalBestId = (bestName != bestId) ? bestId : "";
653
654 auto call = callModel->getCall(convInfo.callId);
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500655 auto isCallSelected = LRCInstance::getSelectedConvUid() == convInfo.uid;
Andreas Traczyk43c08232018-10-31 13:42:09 -0400656
657 if (call.isOutgoing) {
658 if (isCallSelected) {
659 miniSpinner_->start();
660 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
661 ui->spinnerLabel->show();
662 ui->callStackWidget->setCurrentWidget(ui->outgoingCallPage);
663 ui->callStackWidget->show();
664 }
665 } else {
666 if (!QApplication::focusWidget()) {
667 auto formattedName = Utils::bestNameForConversation(convInfo, *convModel);
668 Utils::showSystemNotification(this,
669 QString(tr("Call incoming from %1")).arg(QString::fromStdString(formattedName)));
670 }
671 selectSmartlistItem(convInfo.uid);
672 auto selectedAccountId = LRCInstance::getCurrentAccountInfo().id;
673 auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId);
674 if (accountProperties.autoAnswer) {
675 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
676 ui->callStackWidget->setCurrentWidget(ui->videoPage);
677 } else if (isCallSelected) {
678 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
679 ui->callStackWidget->setCurrentWidget(ui->incomingCallPage);
680 ui->callStackWidget->show();
681 }
682 }
683
Sébastien Blin93bd2062018-12-17 15:57:16 -0500684 if (ui->messagesWidget->isHidden()) {
685 ui->messagesWidget->show();
686 }
687
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400688 ui->videoWidget->pushRenderer(convInfo.callId);
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400689
Andreas Traczyk43c08232018-10-31 13:42:09 -0400690 QFontMetrics primaryCallLabelFontMetrics(ui->callingBestNameLabel->font());
691 QFontMetrics sencondaryCallLabelFontMetrics(ui->callingBestIdLabel->font());
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400692
Andreas Traczyk43c08232018-10-31 13:42:09 -0400693 QString elidedLabel = primaryCallLabelFontMetrics.elidedText(bestName, Qt::ElideRight, ui->callerBestNameLabel->width());
694 ui->callerBestNameLabel->setText(elidedLabel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400695
Andreas Traczyk43c08232018-10-31 13:42:09 -0400696 elidedLabel = primaryCallLabelFontMetrics.elidedText(bestName, Qt::ElideRight, ui->callingBestNameLabel->width());
697 ui->callingBestNameLabel->setText(elidedLabel);
698
699 elidedLabel = sencondaryCallLabelFontMetrics.elidedText(finalBestId, Qt::ElideRight, ui->callingBestIdLabel->width());
700 ui->callingBestIdLabel->setText(elidedLabel);
701
702 ui->smartList->update();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400703}
704
705void CallWidget::slotShowChatView(const std::string& accountId,
Andreas Traczyk43c08232018-10-31 13:42:09 -0400706 const lrc::api::conversation::Info& convInfo)
707{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400708 Q_UNUSED(accountId);
709 Q_UNUSED(convInfo);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400710
Andreas Traczyk43c08232018-10-31 13:42:09 -0400711 ui->callStackWidget->hide();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400712 showConversationView();
Nicolas Jager97a21b42015-12-03 16:55:45 -0500713}
Edric Milaretab12d022015-12-04 16:09:44 -0500714
715void
Sébastien Blin93bd2062018-12-17 15:57:16 -0500716CallWidget::slotToggleFullScreenClicked()
717{
718 if (ui->mainActivityWidget->isFullScreen()) {
719 ui->stackedWidget->addWidget(ui->mainActivityWidget);
720 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
721 ui->mainActivityWidget->showNormal();
722 } else {
723 ui->stackedWidget->removeWidget(ui->mainActivityWidget);
724 ui->mainActivityWidget->setParent(0);
725 ui->mainActivityWidget->showFullScreen();
726 }
727}
728
729void
730CallWidget::slotVideoViewDestroyed(const std::string& callid)
731{
732 auto convUid = LRCInstance::getSelectedConvUid();
733 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
Sébastien Blin93bd2062018-12-17 15:57:16 -0500734 auto conversation = Utils::getConversationFromUid(convUid, *currentConversationModel);
Sébastien Blin62b08ac2018-12-14 16:18:04 -0500735 if (conversation != currentConversationModel->allFilteredConversations().end() &&
736 callid != conversation->callId) {
737 return;
738 }
Sébastien Blin93bd2062018-12-17 15:57:16 -0500739 if (ui->mainActivityWidget->isFullScreen()) {
740 ui->stackedWidget->addWidget(ui->mainActivityWidget);
741 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
742 ui->mainActivityWidget->showNormal();
743 }
744 showConversationView();
745}
746
747void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400748CallWidget::setSelectedAccount(const std::string& accountId)
749{
750 LRCInstance::setSelectedAccountId(accountId);
751
752 // First, we get back to the welcome view (except if in call)
753 if (ui->stackedWidget->currentWidget() != ui->videoPage &&
754 ui->stackedWidget->currentWidget() != ui->welcomePage) {
755 Utils::setStackWidget(ui->stackedWidget, ui->welcomePage);
756 }
757
758 // We setup the ringIdLabel and the QRCode
759 auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
760 auto id = accountInfo.registeredName.empty() ? accountInfo.profileInfo.uri : accountInfo.registeredName;
761 auto isRingAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
762 if (isRingAccount) {
763 ui->ringIdLabel->setText(QString::fromStdString(id));
764 setupQRCode(QString::fromStdString(accountInfo.profileInfo.uri));
765 }
766
767 updateSmartList();
768 currentTypeFilter_ = accountInfo.profileInfo.type;
769 LRCInstance::getCurrentConversationModel()->setFilter(accountInfo.profileInfo.type);
770 updateConversationsFilterWidget();
771 connectConversationModel();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500772 connectAccount(accountId);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400773}
774
775void CallWidget::setConversationFilter(lrc::api::profile::Type filter)
776{
777 if (currentTypeFilter_ == filter) {
778 return;
779 }
780 currentTypeFilter_ = filter;
781 LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
782}
783
784void CallWidget::updateConversationsFilterWidget()
785{
786 auto invites = LRCInstance::getCurrentAccountInfo().contactModel->pendingRequestCount();
787 if (invites == 0 && currentTypeFilter_ == lrc::api::profile::Type::PENDING) {
788 currentTypeFilter_ = lrc::api::profile::Type::RING;
789 LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
790 }
791 ui->conversationsFilterWidget->setVisible(invites);
Andreas Traczyk1d8159a2018-12-13 15:48:24 -0500792 ui->conversationsFilterWidget->updateBadges();
Andreas Traczyk43c08232018-10-31 13:42:09 -0400793 ui->conversationsFilterWidget->update();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400794}
795
796void CallWidget::setConversationFilter(const QString & filter)
797{
798 LRCInstance::getCurrentConversationModel()->setFilter(filter.toStdString());
Anthony Léonardd47179c2017-03-28 10:39:10 -0400799}
800
801void
Edric Milaret6b68a482016-02-01 15:23:44 -0500802CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx)
Edric Milaretab12d022015-12-04 16:09:44 -0500803{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400804 QString displayName = nodeIdx.data(static_cast<int>(SmartListModel::Role::DisplayName)).toString();
805 QString displayId = nodeIdx.data(static_cast<int>(SmartListModel::Role::DisplayID)).toString();
806 QString contactURI = nodeIdx.data(static_cast<int>(SmartListModel::Role::URI)).toString();
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400807
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400808 bool isContact = false;
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500809 auto selectedAccountId = LRCInstance::getCurrAccId();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400810 auto& accountInfo = LRCInstance::accountModel().getAccountInfo(selectedAccountId);
811 bool isRINGAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
812 try {
813 accountInfo.contactModel->getContact(contactURI.toStdString());
814 isContact = true;
815 }
816 catch (...) {}
817
Olivier SOLDANO31b9aac2017-07-14 15:50:09 -0400818 ui->imNameLabel->setText(QString(tr("%1", "%1 is the contact username"))
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400819 .arg(displayName));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400820
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400821 if (isRINGAccount && displayName != displayId){
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400822 ui->imIdLabel->show();
823 ui->imIdLabel->setText(QString(tr("%1", "%1 is the contact unique identifier"))
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400824 .arg(displayId));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400825 } else {
826 ui->imIdLabel->hide();
827 }
828
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400829 bool shouldShowSendContactRequestBtn = !isContact && isRINGAccount;
Andreas Traczyk912242e2018-10-29 14:44:44 -0400830 ui->sendContactRequestButton->setVisible(shouldShowSendContactRequestBtn);
Olivier SOLDANO815d92f2017-07-13 14:05:36 -0400831
Andreas Traczyk43c08232018-10-31 13:42:09 -0400832 auto convModel = LRCInstance::getCurrentConversationModel();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500833 auto currentConversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(),
Andreas Traczyk43c08232018-10-31 13:42:09 -0400834 *convModel);
835 ui->messageView->clear();
Andreas Traczyk43865372018-12-27 12:12:35 -0500836 ui->messageView->printHistory(*convModel, currentConversation->interactions, true);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400837
Andreas Traczyk43c08232018-10-31 13:42:09 -0400838 // Contact Avatars
839 auto accInfo = &LRCInstance::getCurrentAccountInfo();
840 auto contactUri = currentConversation->participants.front();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400841 try {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400842 auto& contact = accInfo->contactModel->getContact(contactUri);
Sébastien Blin942d1022018-12-13 09:49:03 -0500843 auto bestName = Utils::bestNameForConversation(*currentConversation, *convModel);
844 ui->messageView->setInvitation(
845 (contact.profileInfo.type == lrc::api::profile::Type::PENDING),
846 bestName,
847 accInfo->contactModel->getContactProfileId(contact.profileInfo.uri)
848 );
Andreas Traczyk43c08232018-10-31 13:42:09 -0400849 if (!contact.profileInfo.avatar.empty()) {
850 ui->messageView->setSenderImage(
851 accInfo->contactModel->getContactProfileId(contactUri),
852 contact.profileInfo.avatar);
853 } else {
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500854 auto avatar = Utils::conversationPhoto(LRCInstance::getSelectedConvUid(), *accInfo);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400855 QByteArray ba;
856 QBuffer bu(&ba);
857 avatar.save(&bu, "PNG");
858 std::string avatarString = ba.toBase64().toStdString();
859 ui->messageView->setSenderImage(
860 accInfo->contactModel->getContactProfileId(contactUri),
861 avatarString);
862 }
863 } catch (...) { }
Edric Milaretab12d022015-12-04 16:09:44 -0500864}
Edric Milaretfa05d972016-01-13 16:22:04 -0500865
866void
Edric Milaret8001f6f2016-01-27 09:55:12 -0500867CallWidget::on_ringContactLineEdit_textChanged(const QString& text)
Edric Milaretfa05d972016-01-13 16:22:04 -0500868{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400869 Q_UNUSED(text);
870 processContactLineEdit();
Edric Milaretfa05d972016-01-13 16:22:04 -0500871}
Edric Milareta0ebd062016-01-13 12:18:23 -0500872
Nicolas Jagerca850292016-01-17 14:11:10 -0500873void
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400874CallWidget::backToWelcomePage()
Edric Milareta0ebd062016-01-13 12:18:23 -0500875{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400876 deselectConversation();
Andreas Traczyk43c08232018-10-31 13:42:09 -0400877 ui->messageView->hideMessages();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400878 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Nicolas Jagerca850292016-01-17 14:11:10 -0500879}
880
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400881void
882CallWidget::hideMiniSpinner()
Olivier SOLDANO19193412017-06-06 12:03:36 -0400883{
884 if(ui->spinnerLabel->isVisible()){
885 miniSpinner_->stop();
886 ui->spinnerLabel->hide();
887 }
888}
889
Nicolas Jagerca850292016-01-17 14:11:10 -0500890void
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400891CallWidget::on_imBackButton_clicked()
892{
893 backToWelcomePage();
894}
895
896void
Edric Milaret1e598592016-09-02 10:10:01 -0400897CallWidget::on_qrButton_toggled(bool checked)
898{
899 ui->qrLabel->setVisible(checked);
900}
901
902void
Edric Milaret4097d2f2016-02-09 14:41:50 -0500903CallWidget::on_shareButton_clicked()
904{
Sébastien Blincba5b522018-12-10 12:48:36 -0500905 Utils::InvokeMailto(tr("Contact me on Jami"), tr("My Id is : ") + ui->ringIdLabel->text());
Edric Milaret4097d2f2016-02-09 14:41:50 -0500906}
Anthony Léonardaa90e1a2016-10-12 11:24:17 -0400907
908void
Andreas Traczyk912242e2018-10-29 14:44:44 -0400909CallWidget::on_sendContactRequestButton_clicked()
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400910{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500911 LRCInstance::getCurrentConversationModel()->makePermanent(LRCInstance::getSelectedConvUid());
Andreas Traczyk43865372018-12-27 12:12:35 -0500912 ui->sendContactRequestButton->hide();
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400913}
914
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400915void
Andreas Traczyk912242e2018-10-29 14:44:44 -0400916CallWidget::on_btnAudioCall_clicked()
917{
918 auto convUid = LRCInstance::getSelectedConvUid();
919 LRCInstance::getCurrentConversationModel()->placeAudioOnlyCall(convUid);
920 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
921}
922
923void
924CallWidget::on_btnVideoCall_clicked()
925{
926 auto convUid = LRCInstance::getSelectedConvUid();
927 LRCInstance::getCurrentConversationModel()->placeCall(convUid);
928 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
929}
930
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400931bool
932CallWidget::connectConversationModel()
Anthony Léonard5cc76412017-04-21 16:52:25 -0400933{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400934 auto currentConversationModel = LRCInstance::getCurrentAccountInfo().conversationModel.get();
935
936 if (ui->smartList->selectionModel()) {
937 ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect);
Anthony Léonard5cc76412017-04-21 16:52:25 -0400938 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400939
940 QObject::disconnect(modelSortedConnection_);
941 QObject::disconnect(modelUpdatedConnection_);
942 QObject::disconnect(filterChangedConnection_);
943 QObject::disconnect(newConversationConnection_);
944 QObject::disconnect(conversationRemovedConnection_);
945 QObject::disconnect(conversationClearedConnection);
946 QObject::disconnect(interactionStatusUpdatedConnection_);
947 QObject::disconnect(newInteractionConnection_);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400948 QObject::disconnect(interactionRemovedConnection_);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400949
950 modelSortedConnection_ = QObject::connect(
951 currentConversationModel, &lrc::api::ConversationModel::modelSorted,
952 [this]() {
953 updateConversationsFilterWidget();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500954 selectSmartlistItem(LRCInstance::getSelectedConvUid());
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400955 ui->smartList->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400956 }
957 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400958 modelUpdatedConnection_ = QObject::connect(
959 currentConversationModel, &lrc::api::ConversationModel::conversationUpdated,
960 [this](const std::string& convUid) {
961 Q_UNUSED(convUid);
962 ui->smartList->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400963 }
964 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400965 filterChangedConnection_ = QObject::connect(
966 currentConversationModel, &lrc::api::ConversationModel::filterChanged,
967 [this]() {
968 updateSmartList();
969 updateConversationsFilterWidget();
970 ui->smartList->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400971 }
972 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400973 newConversationConnection_ = QObject::connect(
974 currentConversationModel, &lrc::api::ConversationModel::newConversation,
975 [this](const std::string& convUid) {
976 updateSmartList();
977 updateConversationForNewContact(convUid);
978 ui->conversationsFilterWidget->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400979 }
980 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400981 conversationRemovedConnection_ = QObject::connect(
982 currentConversationModel, &lrc::api::ConversationModel::conversationRemoved,
983 [this]() {
984 backToWelcomePage();
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400985 }
986 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400987 conversationClearedConnection = QObject::connect(
988 currentConversationModel, &lrc::api::ConversationModel::conversationCleared,
989 [this](const std::string& convUid) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400990 ui->messageView->clear();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400991 // if currently selected,
992 // switch to welcome screen (deselecting current smartlist item )
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500993 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400994 return;
995 }
996 backToWelcomePage();
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400997 }
998 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400999 interactionStatusUpdatedConnection_ = QObject::connect(
1000 currentConversationModel, &lrc::api::ConversationModel::interactionStatusUpdated,
Andreas Traczyk43c08232018-10-31 13:42:09 -04001001 [this](const std::string& convUid, uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001002 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001003 return;
1004 }
Andreas Traczyk43c08232018-10-31 13:42:09 -04001005 auto& currentAccountInfo = LRCInstance::getCurrentAccountInfo();
1006 auto currentConversationModel = currentAccountInfo.conversationModel.get();
1007 currentConversationModel->clearUnreadInteractions(convUid);
1008 ui->conversationsFilterWidget->update();
1009 ui->messageView->updateInteraction(*currentConversationModel, interactionId, interaction);
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001010 }
1011 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001012 newInteractionConnection_ = QObject::connect(
1013 currentConversationModel, &lrc::api::ConversationModel::newInteraction,
1014 [this](const std::string& convUid, uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
1015 onIncomingMessage(convUid, interactionId, interaction);
Andreas Traczyk4b4bfde2018-12-19 09:53:22 -05001016 if (interaction.type == lrc::api::interaction::Type::CALL) {
1017 return;
1018 }
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001019 if (convUid == LRCInstance::getSelectedConvUid()) {
Andreas Traczyk4b4bfde2018-12-19 09:53:22 -05001020 ui->videoWidget->simulateShowChatview(true);
1021 }
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001022 }
1023 );
Andreas Traczyk43c08232018-10-31 13:42:09 -04001024 interactionRemovedConnection_ = QObject::connect(
1025 currentConversationModel, &lrc::api::ConversationModel::interactionRemoved,
1026 [this](const std::string& convUid, uint64_t interactionId) {
1027 Q_UNUSED(convUid);
1028 ui->messageView->removeInteraction(interactionId);
1029 }
1030 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001031 currentConversationModel->setFilter("");
1032 // clear search field
1033 ui->ringContactLineEdit->setText("");
1034 return true;
1035}
1036
1037void
1038CallWidget::updateConversationView(const std::string& convUid)
1039{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001040 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001041 return;
1042 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001043}
1044
1045void
1046CallWidget::selectConversation(const QModelIndex& index)
1047{
1048 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
1049
1050 if (currentConversationModel == nullptr || !index.isValid()) {
1051 return;
1052 }
1053
1054 const auto item = currentConversationModel->filteredConversation(index.row());
1055
1056 if (selectConversation(item, *currentConversationModel)) {
Andreas Traczyk43c08232018-10-31 13:42:09 -04001057 showIMOutOfCall(index);
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001058 auto convUid = LRCInstance::getSelectedConvUid();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001059 if (!lastConvUid_.compare(convUid)) {
1060 return;
1061 }
1062 lastConvUid_.assign(convUid);
1063 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
1064 auto callModel = LRCInstance::getCurrentCallModel();
1065 auto conversation = Utils::getConversationFromUid(convUid, *currentConversationModel);
1066 const auto item = currentConversationModel->filteredConversation(index.row());
Andreas Traczyk43c08232018-10-31 13:42:09 -04001067 if (callModel->hasCall(conversation->callId) && item.callId == conversation->callId) {
1068 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
1069 ui->callStackWidget->show();
1070 return;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001071 }
Andreas Traczyk43c08232018-10-31 13:42:09 -04001072 ui->callStackWidget->hide();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001073 }
Anthony Léonard5cc76412017-04-21 16:52:25 -04001074}
Anthony Léonardecfe7422017-05-04 14:14:37 -04001075
Anthony Léonard041ad392017-07-14 16:44:09 -04001076bool
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001077CallWidget::selectConversation( const lrc::api::conversation::Info& item,
1078 lrc::api::ConversationModel& convModel)
Anthony Léonard041ad392017-07-14 16:44:09 -04001079{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001080 if (LRCInstance::getSelectedConvUid() == item.uid) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001081 return false;
1082 } else if (item.participants.size() > 0) {
1083 convModel.selectConversation(item.uid);
1084 LRCInstance::setSelectedConvId(item.uid);
1085 convModel.clearUnreadInteractions(item.uid);
1086 ui->conversationsFilterWidget->update();
1087 return true;
Anthony Léonard041ad392017-07-14 16:44:09 -04001088 }
Anthony Léonard041ad392017-07-14 16:44:09 -04001089}
1090
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001091void
1092CallWidget::deselectConversation()
Anthony Léonardecfe7422017-05-04 14:14:37 -04001093{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001094 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
1095
1096 if (currentConversationModel == nullptr) {
1097 return;
1098 }
1099
1100 currentConversationModel->selectConversation("");
1101 LRCInstance::setSelectedConvId("");
1102
1103 ui->smartList->selectionModel()->clear();
1104 disconnect(imConnection_);
Anthony Léonardecfe7422017-05-04 14:14:37 -04001105}
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001106
1107void
1108CallWidget::updateConversationForNewContact(const std::string& convUid)
1109{
1110 auto convModel = LRCInstance::getCurrentConversationModel();
1111 if (convModel == nullptr) {
1112 return;
1113 }
1114 ui->ringContactLineEdit->setText("");
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001115 auto selectedUid = LRCInstance::getSelectedConvUid();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001116 auto it = Utils::getConversationFromUid(convUid, *convModel);
1117 if (it != convModel->allFilteredConversations().end()) {
1118 try {
1119 auto contact = convModel->owner.contactModel->getContact(it->participants[0]);
1120 if (!contact.profileInfo.uri.empty() && contact.profileInfo.uri.compare(selectedUid) == 0) {
1121 LRCInstance::setSelectedConvId(convUid);
1122 convModel->selectConversation(convUid);
1123 }
1124 } catch (...) {
1125 return;
1126 }
1127 }
1128}
1129
1130void
1131CallWidget::updateSmartList()
1132{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001133 if (!ui->smartList->model()) {
1134 smartListModel_.reset(new SmartListModel(LRCInstance::getCurrAccId(), this));
1135 ui->smartList->setModel(smartListModel_.get());
1136 ui->smartList->setItemDelegate(new ConversationItemDelegate());
1137 } else {
1138 smartListModel_->setAccount(LRCInstance::getCurrAccId());
1139 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001140
1141 // smartlist selection
1142 QObject::disconnect(smartlistSelectionConnection_);
1143 smartlistSelectionConnection_ = connect(ui->smartList->selectionModel(),
1144 SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
1145 this,
1146 SLOT(smartListSelectionChanged(QItemSelection, QItemSelection)));
1147}
1148
1149void
Isa Nanic6e4a39a2018-12-04 14:26:02 -05001150CallWidget::updateComboBox()
1151{
1152 ui->currentAccountComboBox->updateComboBoxDisplay();
1153}
1154
1155void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001156CallWidget::update()
1157{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001158 updateSmartList();
1159 updateConversationsFilterWidget();
Isa Nanic6e4a39a2018-12-04 14:26:02 -05001160 updateComboBox();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001161 connectConversationModel();
Isa Nanic601de1d2018-10-23 11:37:26 -04001162}
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001163
1164void
1165CallWidget::connectAccount(const std::string& accId)
1166{
1167 auto callModel = LRCInstance::accountModel().getAccountInfo(accId).callModel.get();
1168 disconnect(callStatusChangedConnection_);
1169 callStatusChangedConnection_ = QObject::connect(callModel, &lrc::api::NewCallModel::callStatusChanged,
1170 [this, accId](const std::string& callId) {
1171 auto callModel = LRCInstance::accountModel().getAccountInfo(accId).callModel.get();
1172 auto call = callModel->getCall(callId);
1173 switch (call.status) {
1174 case lrc::api::call::Status::INVALID:
1175 case lrc::api::call::Status::INACTIVE:
1176 case lrc::api::call::Status::ENDED:
1177 case lrc::api::call::Status::PEER_BUSY:
1178 case lrc::api::call::Status::TIMEOUT:
1179 case lrc::api::call::Status::TERMINATING:
1180 {
1181 ui->callStackWidget->hide();
1182 showConversationView();
1183 break;
1184 }
1185 default:
1186 break;
1187 }
1188 });
1189 auto& contactModel = LRCInstance::getCurrentAccountInfo().contactModel;
1190 disconnect(contactAddedConnection_);
1191 contactAddedConnection_ = connect(contactModel.get(), &lrc::api::ContactModel::contactAdded,
1192 [this, &contactModel](const std::string & contactId) {
1193 auto convModel = LRCInstance::getCurrentConversationModel();
1194 auto currentConversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(),
1195 *convModel);
1196 if (currentConversation == convModel->allFilteredConversations().end()) {
1197 return;
1198 }
1199 if (contactId == contactModel.get()->getContact((*currentConversation).participants.at(0)).profileInfo.uri) {
1200 ui->messageView->clear();
1201 ui->messageView->printHistory(*convModel, currentConversation->interactions);
1202 }
1203 });
1204}