blob: 48e63b5f0f3f837f4bfcdefa29c418b6cecbcb38 [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> *
Edric Milaret627500d2015-03-27 16:41:40 -04007 * *
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, see <http://www.gnu.org/licenses/>. *
20 **************************************************************************/
21
22#include "callwidget.h"
23#include "ui_callwidget.h"
24
Edric Milaret43f3c1e2015-07-16 17:52:47 -040025#include <QClipboard>
Edric Milaret70ae8782016-04-18 16:10:44 -040026#include <QDesktopServices>
Edric Milaret43f3c1e2015-07-16 17:52:47 -040027
Edric Milaret53f57b62015-05-11 11:02:17 -040028#include <memory>
Edric Milaret627500d2015-03-27 16:41:40 -040029
Edric Milarete19c4cd2016-02-12 10:19:44 -050030#include "qrencode.h"
31
Edric Milaret43f3c1e2015-07-16 17:52:47 -040032//ERROR is defined in windows.h
33#include "utils.h"
34#undef ERROR
Edric Milareta0ebd062016-01-13 12:18:23 -050035#undef interface
Edric Milaret43f3c1e2015-07-16 17:52:47 -040036
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040037// lrc
Edric Milareta0ebd062016-01-13 12:18:23 -050038#include "globalinstances.h"
Olivier SOLDANO69361192017-04-20 10:32:05 -040039#include "profilemodel.h"
Olivier SOLDANO69361192017-04-20 10:32:05 -040040#include "localprofilecollection.h"
Anthony Léonardd47179c2017-03-28 10:39:10 -040041
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040042// client
Edric Milaret559bda52015-04-29 17:02:31 -040043#include "wizarddialog.h"
Edric Milaret83b248c2015-06-02 11:42:23 -040044#include "windowscontactbackend.h"
Edric Milaret43f3c1e2015-07-16 17:52:47 -040045#include "contactpicker.h"
Edric Milaret2cf34292015-06-22 16:27:03 -040046#include "globalsystemtray.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040047#include "conversationitemdelegate.h"
Edric Milaretab12d022015-12-04 16:09:44 -050048#include "imdelegate.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050049#include "pixbufmanipulator.h"
Edric Milaret70ae8782016-04-18 16:10:44 -040050#include "settingskey.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040051#include "lrcinstance.h"
52#include "messagemodel.h"
Edric Milaret25236d92016-03-28 09:40:58 -040053
Nicolas Jager97a21b42015-12-03 16:55:45 -050054CallWidget::CallWidget(QWidget* parent) :
Nicolas Jager74fe46f2016-02-29 14:55:09 -050055 NavWidget(parent),
Edric Milaret7d40a4a2015-05-13 13:01:15 -040056 ui(new Ui::CallWidget),
Edric Milaretab12d022015-12-04 16:09:44 -050057 menu_(new QMenu()),
58 imDelegate_(new ImDelegate())
Edric Milaret627500d2015-03-27 16:41:40 -040059{
60 ui->setupUi(this);
61
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040062 using namespace lrc::api;
Nicolas Jagerca850292016-01-17 14:11:10 -050063
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040064 QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
Edric Milaret3aca8e32015-06-12 10:01:40 -040065
Edric Milareted0b2802015-10-01 15:10:02 -040066 QPixmap logo(":/images/logo-ring-standard-coul.png");
67 ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
68 ui->ringLogo->setAlignment(Qt::AlignHCenter);
69
Edric Milaret1e598592016-09-02 10:10:01 -040070 ui->qrLabel->hide();
Edric Milarete19c4cd2016-02-12 10:19:44 -050071
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040072 videoRenderer_ = nullptr;
Edric Milaret627500d2015-03-27 16:41:40 -040073
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040074 // this line is not welcome here, and must be removed
75 ProfileModel::instance().addCollection<LocalProfileCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -040076
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040077 // select last used account if stored in registry
78 auto accountList = LRCInstance::accountModel().getAccountList();
79 if (!accountList.empty()) {
80 std::string accountIdToStartWith;
81 QSettings settings;
82 if (settings.contains(SettingsKey::selectedAccount)) {
83 accountIdToStartWith = settings
84 .value(SettingsKey::selectedAccount, true)
85 .value<QString>()
86 .toStdString();
87 if (Utils::indexInVector(accountList, accountIdToStartWith) == -1) {
88 accountIdToStartWith = accountList.at(0);
Olivier SOLDANOaf8f2822017-07-11 12:15:18 -040089 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040090 }
91 else {
92 accountIdToStartWith = accountList.at(0);
93 }
94 setSelectedAccount(accountIdToStartWith);
95 // get account index and set the currentAccountWidget selector
96 auto index = Utils::indexInVector(accountList, accountIdToStartWith);
97 if (index != -1) {
98 ui->currentAccountWidget->changeSelectedIndex(index);
99 }
Edric Milaret627500d2015-03-27 16:41:40 -0400100 }
Olivier SOLDANO2100f1c2017-09-06 16:45:20 -0400101
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400102 // conversation list
103 conversationItemDelegate_ = new ConversationItemDelegate();
104 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
105
106 // setup searchingfor mini spinner
107 miniSpinner_ = new QMovie(":/images/waiting.gif");
108 ui->spinnerLabel->setMovie(miniSpinner_);
109 ui->spinnerLabel->hide();
110
Olivier SOLDANO2100f1c2017-09-06 16:45:20 -0400111 setupOutOfCallIM();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400112
113 // connections
114 connect(ui->settingsButton, &QPushButton::clicked,
115 this, &CallWidget::settingsButtonClicked);
116
117 connect(ui->videoWidget, SIGNAL(setChatVisibility(bool)),
118 ui->instantMessagingWidget, SLOT(setVisible(bool)));
119
120 connect(ui->videoWidget, &VideoView::videoSettingsClicked,
121 this, &CallWidget::settingsButtonClicked);
122
123 connect(ui->buttonConversations, &QPushButton::clicked,
124 this, &CallWidget::conversationsButtonClicked);
125
126 connect(ui->buttonInvites, &QPushButton::clicked,
127 this, &CallWidget::invitationsButtonClicked);
128
129 connect(ui->currentAccountWidget, &CurrentAccountWidget::currentAccountChanged,
130 this, &CallWidget::currentAccountChanged);
131
132 // TODO(new lrc)
133 connect(&ProfileModel::instance(), &ProfileModel::dataChanged,
134 ui->currentAccountWidget, &CurrentAccountWidget::setPhoto);
135
136 connect(ui->smartList, &QListView::customContextMenuRequested,
137 this, &CallWidget::slotCustomContextMenuRequested);
138
139 connect(ui->smartList, &SmartListView::btnAcceptInviteClicked,
140 this, &CallWidget::slotAcceptInviteClicked);
141
142 connect(ui->smartList, &SmartListView::btnBlockInviteClicked,
143 this, &CallWidget::slotBlockInviteClicked);
144
145 connect(ui->smartList, &SmartListView::btnIgnoreInviteClicked,
146 this, &CallWidget::slotIgnoreInviteClicked);
147
148 connect(&LRCInstance::behaviorController(), &BehaviorController::showCallView,
149 this, &CallWidget::slotShowCallView);
150
151 connect(&LRCInstance::behaviorController(), &BehaviorController::showIncomingCallView,
152 this, &CallWidget::slotShowIncomingCallView);
153
154 connect(&LRCInstance::behaviorController(), &BehaviorController::showChatView,
155 this, &CallWidget::slotShowChatView);
Andreas Traczyk55f92cb2018-10-23 12:26:25 -0400156
157 // set first view to welcome view
158 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400159}
160
161CallWidget::~CallWidget()
162{
163 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400164 delete menu_;
Edric Milaretab12d022015-12-04 16:09:44 -0500165 delete imDelegate_;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400166 delete conversationItemDelegate_;
Edric Milarete19c4cd2016-02-12 10:19:44 -0500167}
168
169void
Edric Milareta0ebd062016-01-13 12:18:23 -0500170CallWidget::setupOutOfCallIM()
171{
172 ui->listMessageView->setItemDelegate(imDelegate_);
173 ui->listMessageView->setContextMenuPolicy(Qt::ActionsContextMenu);
174
175 auto copyAction = new QAction(tr("Copy"), this);
176 ui->listMessageView->addAction(copyAction);
Olivier SOLDANO1f41a0d2017-08-18 16:30:20 -0400177
Edric Milareta0ebd062016-01-13 12:18:23 -0500178 connect(copyAction, &QAction::triggered, [=]() {
179 auto idx = ui->listMessageView->currentIndex();
180 if (idx.isValid()) {
181 auto text = ui->listMessageView->model()->data(idx);
182 QApplication::clipboard()->setText(text.value<QString>());
183 }
184 });
Edric Milaret00a32252016-01-19 10:37:13 -0500185}
186
187void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400188CallWidget::onIncomingMessage(const std::string& convUid,
189 uint64_t interactionId,
190 const lrc::api::interaction::Info& interaction)
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400191{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400192 Q_UNUSED(interactionId);
Edric Milaret00a32252016-01-19 10:37:13 -0500193 if (!QApplication::focusWidget()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400194 Utils::showSystemNotification(this,
195 QString(tr("Message incoming from %1"))
196 .arg(QString::fromStdString(interaction.body)));
Edric Milaret00a32252016-01-19 10:37:13 -0500197 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400198 updateConversationView(convUid);
199 ui->conversationsFilterWidget->update();
Edric Milareta0ebd062016-01-13 12:18:23 -0500200}
201
202void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400203CallWidget::setupSmartListContextMenu(const QPoint& pos)
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400204{
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400205 QPoint globalPos = ui->smartList->mapToGlobal(pos);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400206 auto index = ui->smartList->indexAt(pos);
207 if (not index.isValid()) {
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400208 return;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400209 }
210
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400211 auto convModel = LRCInstance::getCurrentConversationModel();
212 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID))
213 .value<QString>()
214 .toStdString();
215 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
216 auto contactUid = (*conversation).participants.at(0);
217 auto contact = LRCInstance::getCurrentAccountInfo().contactModel.get()->getContact(contactUid);
218
219 if (!Utils::isContactValid(contactUid, *convModel)) {
220 return;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400221 }
222
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400223 QMenu menu;
224
225 // video call
226 auto videoCallAction = new QAction(tr("Start video call"), this);
227 menu.addAction(videoCallAction);
228 connect(videoCallAction, &QAction::triggered,
229 [this, convUid, conversation, convModel]() {
230 convModel->placeCall(convUid);
231 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
232 if (convUid != selectedConvUid()) {
233 selectConversation(*conversation, *convModel);
234 }
235 });
236 // audio call
237 auto audioCallAction = new QAction(tr("Start audio call"), this);
238 menu.addAction(audioCallAction);
239 connect(audioCallAction, &QAction::triggered,
240 [this, convUid, conversation, convModel]() {
241 convModel->placeAudioOnlyCall(convUid);
242 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
243 if (convUid != selectedConvUid()) {
244 selectConversation(*conversation, *convModel);
245 }
246 });
247
248 if (contact.profileInfo.type == lrc::api::profile::Type::RING) {
249 // separator
250 menu.addSeparator();
251
252 // clear conversation
253 auto clearConversationAction = new QAction(tr("Clear conversation"), this);
254 menu.addAction(clearConversationAction);
255 connect(clearConversationAction, &QAction::triggered,
256 [convUid]() {
257 LRCInstance::getCurrentConversationModel()->clearHistory(convUid);
258 });
259 // block contact
260 auto blockContactAction = new QAction(tr("Block contact"), this);
261 menu.addAction(blockContactAction);
262 connect(blockContactAction, &QAction::triggered,
263 [convUid]() {
264 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, true);
265 });
266
267 // separator
268 menu.addSeparator();
269
270 // copy number(infohash)
271 auto copyNumberAction = new QAction(tr("Copy number"), this);
272 menu.addAction(copyNumberAction);
273 connect(copyNumberAction, &QAction::triggered,
274 [contact]() {
275 QApplication::clipboard()->setText(
276 QString::fromStdString(contact.profileInfo.uri)
277 );
278 });
279 }
280 smartListModel_->isContextMenuOpen_ = true;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400281 menu.exec(globalPos);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400282 smartListModel_->isContextMenuOpen_ = false;
Edric Milareta0ebd062016-01-13 12:18:23 -0500283}
284
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400285void
286CallWidget::setupQRCode(QString ringID)
Edric Milarete19c4cd2016-02-12 10:19:44 -0500287{
Anthony Léonarda86a8972016-12-15 10:33:47 -0500288 auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
Edric Milaret6d0e5312016-04-04 16:30:22 -0400289 0, //Let the version be decided by libqrencode
290 QR_ECLEVEL_L, // Lowest level of error correction
Edric Milarete19c4cd2016-02-12 10:19:44 -0500291 QR_MODE_8, // 8-bit data mode
292 1);
293 if (not rcode) {
294 qWarning() << "Failed to generate QR code: " << strerror(errno);
295 return;
296 }
297
298 auto margin = 5;
299 int qrwidth = rcode->width + margin * 2;
300 QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
301 QPainter painter;
302 painter.begin(&result);
303 painter.setClipRect(QRect(0, 0, qrwidth, qrwidth));
304 painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
305 painter.setBrush(Qt::black);
306 painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
Edric Milaret74474f52016-05-16 13:36:23 -0400307 unsigned char* p;
Edric Milarete19c4cd2016-02-12 10:19:44 -0500308 p = rcode->data;
309 for(int y = 0; y < rcode->width; y++) {
Edric Milaret74474f52016-05-16 13:36:23 -0400310 unsigned char* row = (p + (y * rcode->width));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500311 for(int x = 0; x < rcode->width; x++) {
312 if(*(row + x) & 0x1) {
313 painter.drawRect(margin + x, margin + y, 1, 1);
314 }
315 }
316
317 }
318 painter.end();
319 QRcode_free(rcode);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400320 ui->qrLabel->setPixmap(QPixmap::fromImage(result.scaled(QSize(qrSize_, qrSize_),
321 Qt::KeepAspectRatio)));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500322}
323
Edric Milaret627500d2015-03-27 16:41:40 -0400324void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400325CallWidget::on_smartList_clicked(const QModelIndex& index)
Edric Milaret00d34f22016-05-09 16:30:29 -0400326{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400327 Q_UNUSED(index);
Edric Milaret627500d2015-03-27 16:41:40 -0400328}
329
330void
331CallWidget::on_acceptButton_clicked()
332{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400333 auto convModel = LRCInstance::getCurrentConversationModel();
334 auto callModel = LRCInstance::getCurrentCallModel();
335 auto conversation = Utils::getConversationFromUid(selectedConvUid(), *convModel);
336 callModel->accept(conversation->callId);
Edric Milaret627500d2015-03-27 16:41:40 -0400337}
338
339void
340CallWidget::on_refuseButton_clicked()
341{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400342 auto convModel = LRCInstance::getCurrentConversationModel();
343 auto conversation = Utils::getConversationFromUid(selectedConvUid(), *convModel);
344 LRCInstance::getCurrentCallModel()->hangUp(conversation->callId);
345 showConversationView();
Edric Milaret6456baa2015-05-21 12:18:07 -0400346}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400347
348void
Edric Milareted0b2802015-10-01 15:10:02 -0400349CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400350{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400351 auto convModel = LRCInstance::getCurrentConversationModel();
352 auto conversation = Utils::getConversationFromUid(selectedConvUid(), *convModel);
353 LRCInstance::getCurrentCallModel()->hangUp(conversation->callId);
354 showConversationView();
Edric Milaretd8528fa2015-07-07 14:13:51 -0400355}
Edric Milareted0b2802015-10-01 15:10:02 -0400356
357void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400358CallWidget::showConversationView()
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400359{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400360 ui->stackedWidget->setCurrentWidget(ui->messagingPage);
361 ui->imMessageEdit->clear();
362 ui->imMessageEdit->setFocus();
363 disconnect(imClickedConnection_);
364 imClickedConnection_ = connect(ui->listMessageView, &QListView::clicked, [this](const QModelIndex& index) {
365 auto urlList = index.data(static_cast<int>(media::TextRecording::Role::LinkList)).value<QList<QUrl>>();
366 if (urlList.size() == 1) {
367 QDesktopServices::openUrl(urlList.at(0));
368 } else if (urlList.size()) {
369 //TODO Handle multiple url in one message
370 }
371 });
372}
373
374void
375CallWidget::selectSmartlistItem(const std::string & convUid)
376{
377 if (convUid.empty()) {
378 return;
379 }
380 ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect);
381 auto convModel = LRCInstance::getCurrentConversationModel();
382 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
383 if (conversation == convModel->allFilteredConversations().end()) {
384 return;
385 }
386 auto contactURI = QString::fromStdString((*conversation).participants[0]);
387 if (contactURI.isEmpty() ||
388 convModel->owner.contactModel->getContact(contactURI.toStdString()).profileInfo.type == lrc::api::profile::Type::TEMPORARY) {
389 return;
390 }
391 for (int row = 0; row < smartListModel_->rowCount(); row++) {
392 QModelIndex index = smartListModel_->index(row);
393 auto indexContactURI = index.data(SmartListModel::Role::URI).value<QString>();
394 if (indexContactURI == contactURI) {
395 ui->smartList->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
396 return;
397 }
398 }
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400399}
400
401void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500402CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400403{
Olivier SOLDANO70279d32017-07-18 15:21:34 -0400404 if (!index.isValid())
405 return;
406
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400407 LRCInstance::getCurrentConversationModel()->placeCall(selectedConvUid());
Edric Milareted0b2802015-10-01 15:10:02 -0400408
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400409 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(selectedConvUid())));
410}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500411
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400412QImage
413CallWidget::imageForConv(const std::string& convUid)
414{
415 return Utils::conversationPhoto(convUid, LRCInstance::getCurrentAccountInfo());
416}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500417
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400418const std::string&
419CallWidget::selectedAccountId()
420{
421 return LRCInstance::getSelectedAccountId();
422}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500423
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400424const std::string&
425CallWidget::selectedConvUid()
426{
427 return LRCInstance::getSelectedConvUid();
Edric Milareted0b2802015-10-01 15:10:02 -0400428}
429
430void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400431CallWidget::smartListSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500432{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400433 Q_UNUSED(deselected);
434 QModelIndexList indices = selected.indexes();
435
436 if (indices.isEmpty()) {
Edric Milareted0b2802015-10-01 15:10:02 -0400437 return;
Anthony Léonardecfe7422017-05-04 14:14:37 -0400438 }
Edric Milareted0b2802015-10-01 15:10:02 -0400439
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400440 auto selectedIndex = indices.at(0);
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500441
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400442 if (not selectedIndex.isValid()) {
443 return;
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400444 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400445
446 selectConversation(selectedIndex);
Edric Milareted0b2802015-10-01 15:10:02 -0400447}
448
449void
Anthony Léonardd47179c2017-03-28 10:39:10 -0400450CallWidget::contactReqListCurrentChanged(const QModelIndex &currentIdx, const QModelIndex &previousIdx)
451{
452 Q_UNUSED(previousIdx)
453
Anthony Léonardecfe7422017-05-04 14:14:37 -0400454 if (currentIdx.isValid()) {
455 ui->contactRequestWidget->setCurrentContactRequest(currentIdx);
456 ui->stackedWidget->setCurrentWidget(ui->contactRequestPage);
457 } else {
458 ui->contactRequestWidget->setCurrentContactRequest(QModelIndex());
459 if (ui->stackedWidget->currentWidget() == ui->contactRequestPage)
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400460 Utils::setStackWidget(ui->stackedWidget, ui->welcomePage);
Anthony Léonardecfe7422017-05-04 14:14:37 -0400461 }
Anthony Léonardd47179c2017-03-28 10:39:10 -0400462}
463
464void
Edric Milareted0b2802015-10-01 15:10:02 -0400465CallWidget::placeCall()
466{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500467 if (ui->ringContactLineEdit->text().isEmpty())
Edric Milareted0b2802015-10-01 15:10:02 -0400468 return;
Nicolas Jager97a21b42015-12-03 16:55:45 -0500469 Call* c = CallModel::instance().dialingCall(PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text()));
Edric Milareted0b2802015-10-01 15:10:02 -0400470 c->performAction(Call::Action::ACCEPT);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500471 ui->ringContactLineEdit->clear();
Edric1bed3f92016-05-19 10:24:48 -0400472 ui->callingPhoto->setPixmap(
473 QPixmap::fromImage(
474 GlobalInstances::pixmapManipulator()
475 .callPhoto(c, QSize(130,130)).value<QImage>()));
Edric Milareted0b2802015-10-01 15:10:02 -0400476}
477
478void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400479CallWidget::conversationsButtonClicked()
480{
481 setConversationFilter(lrc::api::profile::Type::RING);
482}
483
484void
485CallWidget::invitationsButtonClicked()
486{
487 setConversationFilter(lrc::api::profile::Type::PENDING);
488}
489
490void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500491CallWidget::settingsButtonClicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400492{
493 emit NavigationRequested(ScreenEnum::ConfScreen);
494}
495
496void
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400497CallWidget::processContactLineEdit()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500498{
Anthony Léonardaa90e1a2016-10-12 11:24:17 -0400499 auto contactLineText = ui->ringContactLineEdit->text();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400500 setConversationFilter(contactLineText);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500501}
502
503void
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400504CallWidget::on_ringContactLineEdit_returnPressed()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500505{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400506 // select current temporary item and show conversation
507 auto convModel = LRCInstance::getCurrentConversationModel();
508 auto conversations = convModel->allFilteredConversations();
509 auto contactIsValid = Utils::isContactValid(conversations.at(0).participants.at(0), *convModel);
510 if (!conversations.empty() && contactIsValid) {
511 selectConversation(smartListModel_->index(0));
512 }
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400513}
514
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400515void CallWidget::slotAcceptInviteClicked(const QModelIndex & index)
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400516{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400517 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>();
518 LRCInstance::getCurrentConversationModel()->makePermanent(convUid.toStdString());
Nicolas Jager97a21b42015-12-03 16:55:45 -0500519}
520
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400521void CallWidget::slotBlockInviteClicked(const QModelIndex & index)
Nicolas Jager97a21b42015-12-03 16:55:45 -0500522{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400523 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>();
524 LRCInstance::getCurrentConversationModel()->removeConversation(convUid.toStdString(), true);
525}
526
527void CallWidget::slotIgnoreInviteClicked(const QModelIndex & index)
528{
529 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>();
530 LRCInstance::getCurrentConversationModel()->removeConversation(convUid.toStdString());
531}
532
533void CallWidget::slotCustomContextMenuRequested(const QPoint& pos)
534{
535 setupSmartListContextMenu(pos);
536}
537
538void CallWidget::slotShowCallView(const std::string& accountId,
539 const lrc::api::conversation::Info& convInfo)
540{
541 Q_UNUSED(accountId);
542 Q_UNUSED(convInfo);
543 qDebug() << "BehaviorController::showCallView";
544 ui->stackedWidget->setCurrentWidget(ui->videoPage);
545 hideMiniSpinner();
546}
547
548void CallWidget::slotShowIncomingCallView(const std::string& accountId,
549 const lrc::api::conversation::Info& convInfo) {
550 Q_UNUSED(accountId);
551 qDebug() << "BehaviorController::showIncomingCallView";
552 auto callModel = LRCInstance::getCurrentCallModel();
553 auto call = callModel->getCall(convInfo.callId);
554 if (call.isOutgoing) {
555 miniSpinner_->start();
556 ui->spinnerLabel->show();
557 ui->stackedWidget->setCurrentWidget(ui->outboundCallPage);
558 }
559 else {
560 selectSmartlistItem(convInfo.uid);
561 auto selectedAccountId = LRCInstance::getCurrentAccountInfo().id;
562 auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId);
563 if (!accountProperties.autoAnswer) {
564 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
565 }
566 else {
567 ui->stackedWidget->setCurrentWidget(ui->videoPage);
568 }
569 if (!QApplication::focusWidget()) {
570 auto formattedName = Utils::bestNameForConversation(convInfo, *LRCInstance::getCurrentConversationModel());
571 Utils::showSystemNotification(this,
572 QString(tr("Call incoming from %1")).arg(QString::fromStdString(formattedName)));
573 }
574 }
575
576 if (!callModel->hasCall(convInfo.callId)) {
Nicolas Jager97a21b42015-12-03 16:55:45 -0500577 return;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400578 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500579
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400580 ui->videoWidget->pushRenderer(convInfo.callId);
581 // TODO:(new lrc) in call chat
582 //ui->instantMessagingWidget->setMediaText(actualCall_);
583
584 disconnect(selectedCallChanged_);
585 selectedCallChanged_ = connect(
586 callModel,
587 &lrc::api::NewCallModel::callStatusChanged,
588 [this, callModel](const std::string& callUid) {
589 auto call = callModel->getCall(callUid);
590 qDebug() << "NewCallModel::callStatusChanged: " << static_cast<int>(call.status);
591 }
592 );
593
594 ui->callerPhoto->setPixmap(QPixmap::fromImage(imageForConv(selectedConvUid())));
595}
596
597void CallWidget::slotShowChatView(const std::string& accountId,
598 const lrc::api::conversation::Info& convInfo) {
599 Q_UNUSED(accountId);
600 Q_UNUSED(convInfo);
601 qDebug() << "BehaviorController::showChatView";
602 showConversationView();
Nicolas Jager97a21b42015-12-03 16:55:45 -0500603}
Edric Milaretab12d022015-12-04 16:09:44 -0500604
605void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400606CallWidget::currentAccountChanged(const QModelIndex &current)
Anthony Léonardd47179c2017-03-28 10:39:10 -0400607{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400608 if (!current.isValid()) {
Olivier SOLDANO97c4c2d2017-05-08 13:22:44 -0400609 ui->selectBar->hide();
610 ui->ringIdLabel->setText("");
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400611 return;
Anthony Léonardd47179c2017-03-28 10:39:10 -0400612 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400613 if (ui->selectBar->isHidden()){
614 ui->selectBar->show();
615 }
616
617 auto accountId = current.data(static_cast<int>(AccountListModel::Role::ID)).value<QString>().toStdString();
618
619 setSelectedAccount(accountId);
620}
621
622void
623CallWidget::setSelectedAccount(const std::string& accountId)
624{
625 LRCInstance::setSelectedAccountId(accountId);
626
627 // First, we get back to the welcome view (except if in call)
628 if (ui->stackedWidget->currentWidget() != ui->videoPage &&
629 ui->stackedWidget->currentWidget() != ui->welcomePage) {
630 Utils::setStackWidget(ui->stackedWidget, ui->welcomePage);
631 }
632
633 // We setup the ringIdLabel and the QRCode
634 auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
635 auto id = accountInfo.registeredName.empty() ? accountInfo.profileInfo.uri : accountInfo.registeredName;
636 auto isRingAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
637 if (isRingAccount) {
638 ui->ringIdLabel->setText(QString::fromStdString(id));
639 setupQRCode(QString::fromStdString(accountInfo.profileInfo.uri));
640 }
641
642 updateSmartList();
643 currentTypeFilter_ = accountInfo.profileInfo.type;
644 LRCInstance::getCurrentConversationModel()->setFilter(accountInfo.profileInfo.type);
645 updateConversationsFilterWidget();
646 connectConversationModel();
647}
648
649void CallWidget::setConversationFilter(lrc::api::profile::Type filter)
650{
651 if (currentTypeFilter_ == filter) {
652 return;
653 }
654 currentTypeFilter_ = filter;
655 LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
656}
657
658void CallWidget::updateConversationsFilterWidget()
659{
660 auto invites = LRCInstance::getCurrentAccountInfo().contactModel->pendingRequestCount();
661 if (invites == 0 && currentTypeFilter_ == lrc::api::profile::Type::PENDING) {
662 currentTypeFilter_ = lrc::api::profile::Type::RING;
663 LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
664 }
665 ui->conversationsFilterWidget->setVisible(invites);
Andreas Traczyk0a4e7aa2018-10-22 17:27:38 -0400666 ui->missingButtonsDummyWidget->setVisible(!invites);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400667}
668
669void CallWidget::setConversationFilter(const QString & filter)
670{
671 LRCInstance::getCurrentConversationModel()->setFilter(filter.toStdString());
Anthony Léonardd47179c2017-03-28 10:39:10 -0400672}
673
674void
Edric Milaret6b68a482016-02-01 15:23:44 -0500675CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx)
Edric Milaretab12d022015-12-04 16:09:44 -0500676{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400677 QString displayName = nodeIdx.data(static_cast<int>(SmartListModel::Role::DisplayName)).toString();
678 QString displayId = nodeIdx.data(static_cast<int>(SmartListModel::Role::DisplayID)).toString();
679 QString contactURI = nodeIdx.data(static_cast<int>(SmartListModel::Role::URI)).toString();
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400680
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400681 bool isContact = false;
682 auto selectedAccountId = LRCInstance::getSelectedAccountId();
683 auto& accountInfo = LRCInstance::accountModel().getAccountInfo(selectedAccountId);
684 bool isRINGAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
685 try {
686 accountInfo.contactModel->getContact(contactURI.toStdString());
687 isContact = true;
688 }
689 catch (...) {}
690
691 if (!isRINGAccount){
Olivier SOLDANO1f41a0d2017-08-18 16:30:20 -0400692 ui->imMessageEdit->setPlaceholderText("No messaging possible out of call (SIP) ");
693 ui->imMessageEdit->setEnabled(false);
694 ui->sendIMButton->hide();
695 } else {
Olivier SOLDANO1f41a0d2017-08-18 16:30:20 -0400696 ui->imMessageEdit->setPlaceholderText("Type your message here");
697 ui->imMessageEdit->setEnabled(true);
698 ui->sendIMButton->show();
699 }
700
Olivier SOLDANO31b9aac2017-07-14 15:50:09 -0400701 ui->imNameLabel->setText(QString(tr("%1", "%1 is the contact username"))
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400702 .arg(displayName));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400703
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400704 if (isRINGAccount && displayName != displayId){
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400705 ui->imIdLabel->show();
706 ui->imIdLabel->setText(QString(tr("%1", "%1 is the contact unique identifier"))
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400707 .arg(displayId));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400708 } else {
709 ui->imIdLabel->hide();
710 }
711
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400712 bool shouldShowSendContactRequestBtn = !isContact && isRINGAccount;
713 ui->sendContactRequestPageButton->setVisible(shouldShowSendContactRequestBtn);
Olivier SOLDANO815d92f2017-07-13 14:05:36 -0400714
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400715 showConversationView();
Anthony Léonard041ad392017-07-14 16:44:09 -0400716
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400717 auto currentConversation = Utils::getConversationFromUid(selectedConvUid(),
718 *LRCInstance::getCurrentConversationModel());
719 messageModel_.reset(new MessageModel(*currentConversation, accountInfo, this->parent()));
720 ui->listMessageView->setModel(messageModel_.get());
721 ui->listMessageView->scrollToBottom();
Edric Milaretab12d022015-12-04 16:09:44 -0500722}
723
724void
Edric Milaret6a785af2016-03-07 15:39:30 -0500725CallWidget::on_sendIMButton_clicked()
Edric Milaretab12d022015-12-04 16:09:44 -0500726{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400727 auto msg = ui->imMessageEdit->text();
728 if (msg.trimmed().isEmpty()) return;
729 ui->imMessageEdit->clear();
730 try {
731 LRCInstance::getCurrentConversationModel()->sendMessage(selectedConvUid(), msg.toStdString());
732 } catch (...) {
733 qDebug() << "exception when sending message";
Edric Milaretab12d022015-12-04 16:09:44 -0500734 }
735}
736
737void
Edric Milaret6a785af2016-03-07 15:39:30 -0500738CallWidget::on_imMessageEdit_returnPressed()
Edric Milaretab12d022015-12-04 16:09:44 -0500739{
Edric Milaret6a785af2016-03-07 15:39:30 -0500740 on_sendIMButton_clicked();
Edric Milaretab12d022015-12-04 16:09:44 -0500741}
742
Edric Milaretab12d022015-12-04 16:09:44 -0500743void
744CallWidget::slotAccountMessageReceived(const QMap<QString,QString> message,
745 ContactMethod* cm,
Andreas Traczyke86fb3c2018-08-02 17:38:34 -0400746 media::Media::Direction dir)
Edric Milaretab12d022015-12-04 16:09:44 -0500747{
748 Q_UNUSED(message)
Edric Milaretab12d022015-12-04 16:09:44 -0500749 Q_UNUSED(dir)
750
751 ui->listMessageView->scrollToBottom();
Edric Milaret23fd3fa2016-01-15 15:37:35 -0500752 cm->textRecording()->setAllRead();
Edric Milaretab12d022015-12-04 16:09:44 -0500753}
Edric Milaretfa05d972016-01-13 16:22:04 -0500754
755void
Edric Milaret8001f6f2016-01-27 09:55:12 -0500756CallWidget::on_ringContactLineEdit_textChanged(const QString& text)
Edric Milaretfa05d972016-01-13 16:22:04 -0500757{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400758 Q_UNUSED(text);
759 processContactLineEdit();
Edric Milaretfa05d972016-01-13 16:22:04 -0500760}
Edric Milareta0ebd062016-01-13 12:18:23 -0500761
Nicolas Jagerca850292016-01-17 14:11:10 -0500762void
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400763CallWidget::backToWelcomePage()
Edric Milareta0ebd062016-01-13 12:18:23 -0500764{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400765 deselectConversation();
766 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Nicolas Jagerca850292016-01-17 14:11:10 -0500767}
768
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400769void
770CallWidget::hideMiniSpinner()
Olivier SOLDANO19193412017-06-06 12:03:36 -0400771{
772 if(ui->spinnerLabel->isVisible()){
773 miniSpinner_->stop();
774 ui->spinnerLabel->hide();
775 }
776}
777
Nicolas Jagerca850292016-01-17 14:11:10 -0500778void
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400779CallWidget::on_imBackButton_clicked()
780{
781 backToWelcomePage();
782}
783
784void
Edric Milaret1e598592016-09-02 10:10:01 -0400785CallWidget::on_qrButton_toggled(bool checked)
786{
787 ui->qrLabel->setVisible(checked);
788}
789
790void
Edric Milaret4097d2f2016-02-09 14:41:50 -0500791CallWidget::on_shareButton_clicked()
792{
Edric Milaret1e598592016-09-02 10:10:01 -0400793 Utils::InvokeMailto(tr("Contact me on Ring"), tr("My RingId is : ") + ui->ringIdLabel->text());
Edric Milaret4097d2f2016-02-09 14:41:50 -0500794}
Anthony Léonardaa90e1a2016-10-12 11:24:17 -0400795
796void
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400797CallWidget::on_sendContactRequestPageButton_clicked()
798{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400799 LRCInstance::getCurrentConversationModel()->makePermanent(selectedConvUid());
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400800}
801
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400802void
803CallWidget::on_sendCRBackButton_clicked()
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400804{
Anthony Léonardecfe7422017-05-04 14:14:37 -0400805 ui->stackedWidget->setCurrentWidget(ui->messagingPage);
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400806}
Anthony Léonardd47179c2017-03-28 10:39:10 -0400807
808void
809CallWidget::on_pendingCRBackButton_clicked()
810{
Olivier SOLDANO8179e992017-07-19 15:59:19 -0400811 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Anthony Léonardd47179c2017-03-28 10:39:10 -0400812}
Anthony Léonard5cc76412017-04-21 16:52:25 -0400813
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400814bool
815CallWidget::connectConversationModel()
Anthony Léonard5cc76412017-04-21 16:52:25 -0400816{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400817 auto currentConversationModel = LRCInstance::getCurrentAccountInfo().conversationModel.get();
818
819 if (ui->smartList->selectionModel()) {
820 ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect);
Anthony Léonard5cc76412017-04-21 16:52:25 -0400821 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400822
823 QObject::disconnect(modelSortedConnection_);
824 QObject::disconnect(modelUpdatedConnection_);
825 QObject::disconnect(filterChangedConnection_);
826 QObject::disconnect(newConversationConnection_);
827 QObject::disconnect(conversationRemovedConnection_);
828 QObject::disconnect(conversationClearedConnection);
829 QObject::disconnect(interactionStatusUpdatedConnection_);
830 QObject::disconnect(newInteractionConnection_);
831
832 modelSortedConnection_ = QObject::connect(
833 currentConversationModel, &lrc::api::ConversationModel::modelSorted,
834 [this]() {
835 updateConversationsFilterWidget();
836 selectSmartlistItem(selectedConvUid());
837 ui->smartList->update();
838 }
839 );
840 modelUpdatedConnection_ = QObject::connect(
841 currentConversationModel, &lrc::api::ConversationModel::conversationUpdated,
842 [this](const std::string& convUid) {
843 Q_UNUSED(convUid);
844 ui->smartList->update();
845 }
846 );
847 filterChangedConnection_ = QObject::connect(
848 currentConversationModel, &lrc::api::ConversationModel::filterChanged,
849 [this]() {
850 updateSmartList();
851 updateConversationsFilterWidget();
852 ui->smartList->update();
853 }
854 );
855 newConversationConnection_ = QObject::connect(
856 currentConversationModel, &lrc::api::ConversationModel::newConversation,
857 [this](const std::string& convUid) {
858 updateSmartList();
859 updateConversationForNewContact(convUid);
860 ui->conversationsFilterWidget->update();
861 }
862 );
863 conversationRemovedConnection_ = QObject::connect(
864 currentConversationModel, &lrc::api::ConversationModel::conversationRemoved,
865 [this]() {
866 backToWelcomePage();
867 }
868 );
869 conversationClearedConnection = QObject::connect(
870 currentConversationModel, &lrc::api::ConversationModel::conversationCleared,
871 [this](const std::string& convUid) {
872 updateConversationView(convUid);
873 // if currently selected,
874 // switch to welcome screen (deselecting current smartlist item )
875 if (convUid != selectedConvUid()) {
876 return;
877 }
878 backToWelcomePage();
879 }
880 );
881 interactionStatusUpdatedConnection_ = QObject::connect(
882 currentConversationModel, &lrc::api::ConversationModel::interactionStatusUpdated,
883 [this](const std::string& convUid) {
884 if (convUid != selectedConvUid()) {
885 return;
886 }
887 updateConversationView(convUid);
888 }
889 );
890 newInteractionConnection_ = QObject::connect(
891 currentConversationModel, &lrc::api::ConversationModel::newInteraction,
892 [this](const std::string& convUid, uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
893 onIncomingMessage(convUid, interactionId, interaction);
894 }
895 );
896 currentConversationModel->setFilter("");
897 // clear search field
898 ui->ringContactLineEdit->setText("");
899 return true;
900}
901
902void
903CallWidget::updateConversationView(const std::string& convUid)
904{
905 if (convUid != selectedConvUid()) {
906 return;
907 }
908
909 auto& currentAccountInfo = LRCInstance::getCurrentAccountInfo();
910 auto currentConversationModel = currentAccountInfo.conversationModel.get();
911 currentConversationModel->clearUnreadInteractions(convUid);
912 ui->conversationsFilterWidget->update();
913 auto currentConversation = Utils::getConversationFromUid(convUid,
914 *currentConversationModel);
915 if (currentConversation == currentConversationModel->allFilteredConversations().end()) {
916 return;
917 }
918 messageModel_.reset(new MessageModel(*currentConversation, currentAccountInfo, this->parent()));
919 ui->listMessageView->setModel(messageModel_.get());
920 ui->listMessageView->scrollToBottom();
921}
922
923void
924CallWidget::selectConversation(const QModelIndex& index)
925{
926 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
927
928 if (currentConversationModel == nullptr || !index.isValid()) {
929 return;
930 }
931
932 const auto item = currentConversationModel->filteredConversation(index.row());
933
934 if (selectConversation(item, *currentConversationModel)) {
935 auto convUid = selectedConvUid();
936 if (!lastConvUid_.compare(convUid)) {
937 return;
938 }
939 lastConvUid_.assign(convUid);
940 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
941 auto callModel = LRCInstance::getCurrentCallModel();
942 auto conversation = Utils::getConversationFromUid(convUid, *currentConversationModel);
943 const auto item = currentConversationModel->filteredConversation(index.row());
944 if (callModel->hasCall(conversation->callId)) {
945 ui->stackedWidget->setCurrentWidget(ui->videoPage);
946 }
947 else {
948 showIMOutOfCall(index);
949 }
950 }
Anthony Léonard5cc76412017-04-21 16:52:25 -0400951}
Anthony Léonardecfe7422017-05-04 14:14:37 -0400952
Anthony Léonard041ad392017-07-14 16:44:09 -0400953bool
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400954CallWidget::selectConversation( const lrc::api::conversation::Info& item,
955 lrc::api::ConversationModel& convModel)
Anthony Léonard041ad392017-07-14 16:44:09 -0400956{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400957 if (selectedConvUid() == item.uid) {
958 return false;
959 } else if (item.participants.size() > 0) {
960 convModel.selectConversation(item.uid);
961 LRCInstance::setSelectedConvId(item.uid);
962 convModel.clearUnreadInteractions(item.uid);
963 ui->conversationsFilterWidget->update();
964 return true;
Anthony Léonard041ad392017-07-14 16:44:09 -0400965 }
Anthony Léonard041ad392017-07-14 16:44:09 -0400966}
967
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400968void
969CallWidget::deselectConversation()
Anthony Léonardecfe7422017-05-04 14:14:37 -0400970{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400971 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
972
973 if (currentConversationModel == nullptr) {
974 return;
975 }
976
977 currentConversationModel->selectConversation("");
978 LRCInstance::setSelectedConvId("");
979
980 ui->smartList->selectionModel()->clear();
981 disconnect(imConnection_);
Anthony Léonardecfe7422017-05-04 14:14:37 -0400982}
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400983
984void
985CallWidget::updateConversationForNewContact(const std::string& convUid)
986{
987 auto convModel = LRCInstance::getCurrentConversationModel();
988 if (convModel == nullptr) {
989 return;
990 }
991 ui->ringContactLineEdit->setText("");
992 auto selectedUid = selectedConvUid();
993 auto it = Utils::getConversationFromUid(convUid, *convModel);
994 if (it != convModel->allFilteredConversations().end()) {
995 try {
996 auto contact = convModel->owner.contactModel->getContact(it->participants[0]);
997 if (!contact.profileInfo.uri.empty() && contact.profileInfo.uri.compare(selectedUid) == 0) {
998 LRCInstance::setSelectedConvId(convUid);
999 convModel->selectConversation(convUid);
1000 }
1001 } catch (...) {
1002 return;
1003 }
1004 }
1005}
1006
1007void
1008CallWidget::updateSmartList()
1009{
1010 auto& currentAccountInfo = LRCInstance::getCurrentAccountInfo();
1011 smartListModel_.reset(new SmartListModel(currentAccountInfo, this->parent()));
1012 ui->smartList->setModel(smartListModel_.get());
1013 ui->smartList->setItemDelegate(new ConversationItemDelegate());
1014
1015 // smartlist selection
1016 QObject::disconnect(smartlistSelectionConnection_);
1017 smartlistSelectionConnection_ = connect(ui->smartList->selectionModel(),
1018 SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
1019 this,
1020 SLOT(smartListSelectionChanged(QItemSelection, QItemSelection)));
1021}
1022
1023void
1024CallWidget::update()
1025{
1026 ui->currentAccountWidget->update();
1027 updateSmartList();
1028 updateConversationsFilterWidget();
1029 connectConversationModel();
1030}