blob: 31ccd386bc9014aa93c0c31c6e16e73f47cb637e [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Sébastien Blin68abac92019-01-02 17:41:31 -05002 * Copyright (C) 2015-2019 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
Sébastien Blind2e8d0e2019-01-10 14:18:36 -050035#include <qrencode.h>
Edric Milarete19c4cd2016-02-12 10:19:44 -050036
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 Milaret83b248c2015-06-02 11:42:23 -040048#include "windowscontactbackend.h"
Edric Milaret2cf34292015-06-22 16:27:03 -040049#include "globalsystemtray.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040050#include "conversationitemdelegate.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050051#include "pixbufmanipulator.h"
Edric Milaret70ae8782016-04-18 16:10:44 -040052#include "settingskey.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040053#include "lrcinstance.h"
Andreas Traczyk43c08232018-10-31 13:42:09 -040054#include "animationhelpers.h"
55#include "ringthemeutils.h"
Andreas Traczyk868c3d62019-01-03 21:05:40 -050056#include "mainwindow.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
Isa Nanic601de1d2018-10-23 11:37:26 -0400114 //disable dropdown shadow on combobox
115 ui->currentAccountComboBox->view()->window()->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
116
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400117 // conversation list
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400118 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
119
120 // setup searchingfor mini spinner
121 miniSpinner_ = new QMovie(":/images/waiting.gif");
122 ui->spinnerLabel->setMovie(miniSpinner_);
123 ui->spinnerLabel->hide();
124
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400125 // connections
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400126 connect(ui->currentAccountComboBox, &CurrentAccountComboBox::settingsButtonClicked,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400127 this, &CallWidget::settingsButtonClicked);
128
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500129 connect(ui->currentAccountComboBox, &CurrentAccountComboBox::newAccountClicked,
130 [this]() {
131 emit NavigationRequested(ScreenEnum::WizardScreen);
132 });
133
Andreas Traczyk43c08232018-10-31 13:42:09 -0400134 connect(ui->videoWidget, &VideoView::setChatVisibility,
135 [this](bool visible) {
Sébastien Blin93bd2062018-12-17 15:57:16 -0500136 if (visible) {
137 ui->messagesWidget->show();
138 } else {
139 ui->messagesWidget->hide();
140 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400141 });
142
143 connect(ui->mainActivitySplitter, &QSplitter::splitterMoved,
144 [this](int pos, int index) {
Andreas Traczyk14c3e862018-12-26 14:02:30 -0500145 Q_UNUSED(index);
146 Q_UNUSED(pos);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400147 QSettings settings;
148 settings.setValue(SettingsKey::mainSplitterState, ui->mainActivitySplitter->saveState());
149 });
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400150
151 connect(ui->videoWidget, &VideoView::videoSettingsClicked,
152 this, &CallWidget::settingsButtonClicked);
153
Sébastien Blin62b08ac2018-12-14 16:18:04 -0500154 connect(ui->videoWidget, &VideoView::toggleFullScreenClicked,
155 this, &CallWidget::slotToggleFullScreenClicked);
156
157 connect(ui->videoWidget, &VideoView::closing,
158 this, &CallWidget::slotVideoViewDestroyed);
159
Andreas Traczyk43c08232018-10-31 13:42:09 -0400160 connect(ui->btnConversations, &QPushButton::clicked,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400161 this, &CallWidget::conversationsButtonClicked);
162
Andreas Traczyk43c08232018-10-31 13:42:09 -0400163 connect(ui->btnInvites, &QPushButton::clicked,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400164 this, &CallWidget::invitationsButtonClicked);
165
Andreas Traczyk43c08232018-10-31 13:42:09 -0400166 connect(ui->smartList, &QTreeView::customContextMenuRequested,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400167 this, &CallWidget::slotCustomContextMenuRequested);
168
169 connect(ui->smartList, &SmartListView::btnAcceptInviteClicked,
170 this, &CallWidget::slotAcceptInviteClicked);
171
172 connect(ui->smartList, &SmartListView::btnBlockInviteClicked,
173 this, &CallWidget::slotBlockInviteClicked);
174
175 connect(ui->smartList, &SmartListView::btnIgnoreInviteClicked,
176 this, &CallWidget::slotIgnoreInviteClicked);
177
178 connect(&LRCInstance::behaviorController(), &BehaviorController::showCallView,
179 this, &CallWidget::slotShowCallView);
180
181 connect(&LRCInstance::behaviorController(), &BehaviorController::showIncomingCallView,
182 this, &CallWidget::slotShowIncomingCallView);
183
184 connect(&LRCInstance::behaviorController(), &BehaviorController::showChatView,
185 this, &CallWidget::slotShowChatView);
Andreas Traczyk55f92cb2018-10-23 12:26:25 -0400186
Isa Nanic601de1d2018-10-23 11:37:26 -0400187 connect(ui->currentAccountComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
188 this, &CallWidget::slotAccountChanged);
189
Andreas Traczyk912242e2018-10-29 14:44:44 -0400190 connect(ui->sendContactRequestButton, &QPushButton::clicked,
191 this, &CallWidget::on_sendContactRequestButton_clicked);
192
193 connect(ui->btnAudioCall, &QPushButton::clicked,
194 this, &CallWidget::on_sendContactRequestButton_clicked);
195
196 connect(ui->btnVideoCall, &QPushButton::clicked,
197 this, &CallWidget::on_sendContactRequestButton_clicked);
198
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400199 connect(ui->currentAccountComboBox, QOverload<int>::of(&CurrentAccountComboBox::currentIndexChanged),
200 [this] {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400201 ui->btnConversations->setChecked(true);
202 ui->btnInvites->setChecked(false);
203 });
204
Andreas Traczyk43865372018-12-27 12:12:35 -0500205 connect(ui->messageView, &MessageWebView::conversationRemoved,
206 [this] {
207 backToWelcomePage();
208 });
209
Andreas Traczyk55f92cb2018-10-23 12:26:25 -0400210 // set first view to welcome view
211 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400212 ui->btnConversations->setChecked(true);
213
214 // chat view
215 ui->messageView->buildView();
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500216
Andreas Traczykb81281e2018-12-13 13:13:28 -0500217 // hide the call stack
Andreas Traczyk0147bf12019-01-03 20:46:03 -0500218 setCallPanelVisibility(false);
Andreas Traczykfc33a492018-12-14 13:53:13 -0500219
220 ui->containerWidget->setVisible(false);
Edric Milaret627500d2015-03-27 16:41:40 -0400221}
222
223CallWidget::~CallWidget()
224{
225 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400226 delete menu_;
Edric Milaret00a32252016-01-19 10:37:13 -0500227}
228
Andreas Traczykfc33a492018-12-14 13:53:13 -0500229void
230CallWidget::navigated(bool to)
231{
232 ui->containerWidget->setVisible(to);
233 if (to) {
234 updateSmartList();
235 connectConversationModel();
Andreas Traczyk3fc824d2019-01-02 15:20:21 -0500236 try {
237 auto accountList = LRCInstance::accountModel().getAccountList();
238 if (accountList.size() == 1) {
239 auto index = Utils::indexInVector(accountList, LRCInstance::getCurrAccId());
240 if (index != -1) {
241 slotAccountChanged(index);
242 }
243 }
244 } catch (...) {}
Andreas Traczykb15c83a2018-12-31 12:29:25 -0500245 ui->currentAccountComboBox->updateComboBoxDisplay();
Andreas Traczyk39fa4d02019-01-03 17:32:07 -0500246 auto selectedConvUid = LRCInstance::getSelectedConvUid();
247 auto convModel = LRCInstance::getCurrentConversationModel();
248 auto conversation = Utils::getConversationFromUid(selectedConvUid, *convModel);
249 if (!selectedConvUid.empty() && conversation != convModel->allFilteredConversations().end()) {
250 selectSmartlistItem(selectedConvUid);
251 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
252 } else {
253 backToWelcomePage();
254 }
Andreas Traczykfc33a492018-12-14 13:53:13 -0500255 } else {
256 QObject::disconnect(smartlistSelectionConnection_);
257 smartListModel_.reset(nullptr);
258 }
259}
260
Andreas Traczyk59ba48a2019-01-04 16:12:03 -0500261void
262CallWidget::updateCustomUI()
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500263{
Andreas Traczyk868c3d62019-01-03 21:05:40 -0500264 auto scalingRatio = MainWindow::instance().getCurrentScalingRatio();
265 if (scalingRatio > 1.0) {
266 ui->messageView->setZoomFactor(1.15);
267 } else {
268 ui->messageView->setZoomFactor(1.0);
269 }
270
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500271}
272
Andreas Traczykb81281e2018-12-13 13:13:28 -0500273int
274CallWidget::getLeftPanelWidth()
275{
276 return ui->currentAccountComboBox->width();
277}
278
Edric Milaret00a32252016-01-19 10:37:13 -0500279void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400280CallWidget::onIncomingMessage(const std::string& convUid,
281 uint64_t interactionId,
282 const lrc::api::interaction::Info& interaction)
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400283{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400284 Q_UNUSED(interactionId);
Edric Milaret00a32252016-01-19 10:37:13 -0500285 if (!QApplication::focusWidget()) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400286 auto convModel = LRCInstance::getCurrentConversationModel();
287 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
Andreas Traczyk39fa4d02019-01-03 17:32:07 -0500288 if (conversation == convModel->allFilteredConversations().end()) {
289 return;
290 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400291 auto bestName = Utils::bestNameForConversation(*conversation, *convModel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400292 Utils::showSystemNotification(this,
293 QString(tr("Message incoming from %1"))
Andreas Traczyk43c08232018-10-31 13:42:09 -0400294 .arg(QString::fromStdString(bestName)));
Edric Milaret00a32252016-01-19 10:37:13 -0500295 }
Andreas Traczyk1d8159a2018-12-13 15:48:24 -0500296 updateConversationsFilterWidget();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500297 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400298 return;
299 }
300
301 auto convModel = LRCInstance::getCurrentConversationModel();
302 convModel->clearUnreadInteractions(convUid);
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500303 auto convInfo = Utils::getSelectedConversation();
304 if (!convInfo.uid.empty()) {
305 ui->messageView->printNewInteraction(*convModel, interactionId, interaction);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400306 }
Edric Milareta0ebd062016-01-13 12:18:23 -0500307}
308
309void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400310CallWidget::setupSmartListContextMenu(const QPoint& pos)
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400311{
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400312 QPoint globalPos = ui->smartList->mapToGlobal(pos);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400313 auto index = ui->smartList->indexAt(pos);
314 if (not index.isValid()) {
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400315 return;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400316 }
317
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400318 auto convModel = LRCInstance::getCurrentConversationModel();
319 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID))
320 .value<QString>()
321 .toStdString();
322 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
323 auto contactUid = (*conversation).participants.at(0);
324 auto contact = LRCInstance::getCurrentAccountInfo().contactModel.get()->getContact(contactUid);
325
326 if (!Utils::isContactValid(contactUid, *convModel)) {
327 return;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400328 }
329
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400330 QMenu menu;
331
332 // video call
333 auto videoCallAction = new QAction(tr("Start video call"), this);
334 menu.addAction(videoCallAction);
335 connect(videoCallAction, &QAction::triggered,
336 [this, convUid, conversation, convModel]() {
337 convModel->placeCall(convUid);
338 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500339 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400340 selectConversation(*conversation, *convModel);
341 }
342 });
343 // audio call
344 auto audioCallAction = new QAction(tr("Start audio call"), this);
345 menu.addAction(audioCallAction);
346 connect(audioCallAction, &QAction::triggered,
347 [this, convUid, conversation, convModel]() {
348 convModel->placeAudioOnlyCall(convUid);
349 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid)));
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500350 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400351 selectConversation(*conversation, *convModel);
352 }
353 });
354
355 if (contact.profileInfo.type == lrc::api::profile::Type::RING) {
356 // separator
357 menu.addSeparator();
358
359 // clear conversation
360 auto clearConversationAction = new QAction(tr("Clear conversation"), this);
361 menu.addAction(clearConversationAction);
362 connect(clearConversationAction, &QAction::triggered,
363 [convUid]() {
364 LRCInstance::getCurrentConversationModel()->clearHistory(convUid);
365 });
Sébastien Blin31fccce2018-12-13 11:27:05 -0500366 // remove contact
367 auto removeContactAction = new QAction(tr("Remove contact"), this);
368 menu.addAction(removeContactAction);
369 connect(removeContactAction, &QAction::triggered,
370 [convUid]() {
371 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, false);
372 });
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400373 // block contact
374 auto blockContactAction = new QAction(tr("Block contact"), this);
375 menu.addAction(blockContactAction);
376 connect(blockContactAction, &QAction::triggered,
377 [convUid]() {
378 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, true);
379 });
380
381 // separator
382 menu.addSeparator();
383
384 // copy number(infohash)
385 auto copyNumberAction = new QAction(tr("Copy number"), this);
386 menu.addAction(copyNumberAction);
387 connect(copyNumberAction, &QAction::triggered,
388 [contact]() {
389 QApplication::clipboard()->setText(
390 QString::fromStdString(contact.profileInfo.uri)
391 );
392 });
393 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400394 smartListModel_->isContextMenuOpen = true;
Olivier SOLDANOcc28a0d2017-07-21 13:53:31 -0400395 menu.exec(globalPos);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400396 smartListModel_->isContextMenuOpen = false;
Edric Milareta0ebd062016-01-13 12:18:23 -0500397}
398
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400399void
400CallWidget::setupQRCode(QString ringID)
Edric Milarete19c4cd2016-02-12 10:19:44 -0500401{
Anthony Léonarda86a8972016-12-15 10:33:47 -0500402 auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
Edric Milaret6d0e5312016-04-04 16:30:22 -0400403 0, //Let the version be decided by libqrencode
404 QR_ECLEVEL_L, // Lowest level of error correction
Edric Milarete19c4cd2016-02-12 10:19:44 -0500405 QR_MODE_8, // 8-bit data mode
406 1);
407 if (not rcode) {
408 qWarning() << "Failed to generate QR code: " << strerror(errno);
409 return;
410 }
411
412 auto margin = 5;
413 int qrwidth = rcode->width + margin * 2;
414 QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
415 QPainter painter;
416 painter.begin(&result);
417 painter.setClipRect(QRect(0, 0, qrwidth, qrwidth));
418 painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
419 painter.setBrush(Qt::black);
420 painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
Edric Milaret74474f52016-05-16 13:36:23 -0400421 unsigned char* p;
Edric Milarete19c4cd2016-02-12 10:19:44 -0500422 p = rcode->data;
423 for(int y = 0; y < rcode->width; y++) {
Edric Milaret74474f52016-05-16 13:36:23 -0400424 unsigned char* row = (p + (y * rcode->width));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500425 for(int x = 0; x < rcode->width; x++) {
426 if(*(row + x) & 0x1) {
427 painter.drawRect(margin + x, margin + y, 1, 1);
428 }
429 }
430
431 }
432 painter.end();
433 QRcode_free(rcode);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400434 ui->qrLabel->setPixmap(QPixmap::fromImage(result.scaled(QSize(qrSize_, qrSize_),
435 Qt::KeepAspectRatio)));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500436}
437
Edric Milaret627500d2015-03-27 16:41:40 -0400438void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400439CallWidget::on_smartList_clicked(const QModelIndex& index)
Edric Milaret00d34f22016-05-09 16:30:29 -0400440{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400441 Q_UNUSED(index);
Edric Milaret627500d2015-03-27 16:41:40 -0400442}
443
444void
445CallWidget::on_acceptButton_clicked()
446{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500447 auto convInfo = Utils::getSelectedConversation();
448 if (!convInfo.uid.empty()) {
449 LRCInstance::getCurrentCallModel()->accept(convInfo.callId);
450 }
Edric Milaret627500d2015-03-27 16:41:40 -0400451}
452
453void
454CallWidget::on_refuseButton_clicked()
455{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500456 auto convInfo = Utils::getSelectedConversation();
457 if (!convInfo.uid.empty()) {
458 LRCInstance::getCurrentCallModel()->hangUp(convInfo.callId);
459 showConversationView();
460 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400461}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400462
463void
Edric Milareted0b2802015-10-01 15:10:02 -0400464CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400465{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500466 on_refuseButton_clicked();
Edric Milaretd8528fa2015-07-07 14:13:51 -0400467}
Edric Milareted0b2802015-10-01 15:10:02 -0400468
469void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400470CallWidget::showConversationView()
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400471{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500472 if (LRCInstance::getSelectedConvUid().empty()) {
473 backToWelcomePage();
474 return;
475 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400476 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
477 ui->messageView->setFocus();
Sébastien Blin93bd2062018-12-17 15:57:16 -0500478 if (ui->messagesWidget->isHidden()) {
479 ui->messagesWidget->show();
480 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400481}
482
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500483bool
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400484CallWidget::selectSmartlistItem(const std::string & convUid)
485{
Andreas Traczyk9c9d46b2019-01-07 16:13:17 -0500486 if (convUid.empty() || !ui->smartList->selectionModel())
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500487 return false;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400488 ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect);
489 auto convModel = LRCInstance::getCurrentConversationModel();
490 auto conversation = Utils::getConversationFromUid(convUid, *convModel);
491 if (conversation == convModel->allFilteredConversations().end()) {
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500492 return false;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400493 }
494 auto contactURI = QString::fromStdString((*conversation).participants[0]);
495 if (contactURI.isEmpty() ||
496 convModel->owner.contactModel->getContact(contactURI.toStdString()).profileInfo.type == lrc::api::profile::Type::TEMPORARY) {
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500497 return false;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400498 }
499 for (int row = 0; row < smartListModel_->rowCount(); row++) {
500 QModelIndex index = smartListModel_->index(row);
501 auto indexContactURI = index.data(SmartListModel::Role::URI).value<QString>();
502 if (indexContactURI == contactURI) {
503 ui->smartList->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500504 return true;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400505 }
506 }
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500507 return false;
Olivier SOLDANO9657fd12017-03-27 16:06:53 -0400508}
509
510void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500511CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400512{
Olivier SOLDANO70279d32017-07-18 15:21:34 -0400513 if (!index.isValid())
514 return;
515
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500516 selectConversation(index);
517
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500518 LRCInstance::getCurrentConversationModel()->placeCall(LRCInstance::getSelectedConvUid());
Edric Milareted0b2802015-10-01 15:10:02 -0400519
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500520 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(LRCInstance::getSelectedConvUid())));
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400521}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500522
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400523QImage
524CallWidget::imageForConv(const std::string& convUid)
525{
526 return Utils::conversationPhoto(convUid, LRCInstance::getCurrentAccountInfo());
527}
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500528
Edric Milareted0b2802015-10-01 15:10:02 -0400529void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400530CallWidget::smartListSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500531{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400532 Q_UNUSED(deselected);
533 QModelIndexList indices = selected.indexes();
534
535 if (indices.isEmpty()) {
Edric Milareted0b2802015-10-01 15:10:02 -0400536 return;
Anthony Léonardecfe7422017-05-04 14:14:37 -0400537 }
Edric Milareted0b2802015-10-01 15:10:02 -0400538
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400539 auto selectedIndex = indices.at(0);
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500540
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400541 if (not selectedIndex.isValid()) {
542 return;
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400543 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400544
545 selectConversation(selectedIndex);
Edric Milareted0b2802015-10-01 15:10:02 -0400546}
547
548void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400549CallWidget::conversationsButtonClicked()
550{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400551 ui->btnConversations->setChecked(true);
552 ui->btnInvites->setChecked(false);
Andreas Traczykdc17c812019-01-11 15:35:20 -0500553 ui->ringContactLineEdit->setPlaceholderString(tr("Find a new or existing contact"));
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400554 setConversationFilter(lrc::api::profile::Type::RING);
555}
556
557void
558CallWidget::invitationsButtonClicked()
559{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400560 ui->btnConversations->setChecked(false);
561 ui->btnInvites->setChecked(true);
Andreas Traczykdc17c812019-01-11 15:35:20 -0500562 ui->ringContactLineEdit->setPlaceholderString(tr("Search your received invitations"));
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400563 setConversationFilter(lrc::api::profile::Type::PENDING);
564}
565
566void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500567CallWidget::settingsButtonClicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400568{
Andreas Traczyk7548e732018-12-12 10:47:21 -0500569 emit NavigationRequested(ScreenEnum::SetttingsScreen);
Edric Milareted0b2802015-10-01 15:10:02 -0400570}
571
572void
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400573CallWidget::processContactLineEdit()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500574{
Anthony Léonardaa90e1a2016-10-12 11:24:17 -0400575 auto contactLineText = ui->ringContactLineEdit->text();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400576 setConversationFilter(contactLineText);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500577}
578
579void
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400580CallWidget::on_ringContactLineEdit_returnPressed()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500581{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400582 // select current temporary item and show conversation
583 auto convModel = LRCInstance::getCurrentConversationModel();
584 auto conversations = convModel->allFilteredConversations();
Andreas Traczyk43c08232018-10-31 13:42:09 -0400585 if (!conversations.empty() &&
586 Utils::isContactValid(conversations.at(0).participants.at(0), *convModel)) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400587 selectConversation(smartListModel_->index(0));
588 }
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400589}
590
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400591void CallWidget::slotAcceptInviteClicked(const QModelIndex & index)
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400592{
Andreas Traczyk43865372018-12-27 12:12:35 -0500593 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
594 LRCInstance::getCurrentConversationModel()->makePermanent(convUid);
595 ui->messageView->setInvitation(false);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500596}
597
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400598void CallWidget::slotBlockInviteClicked(const QModelIndex & index)
Nicolas Jager97a21b42015-12-03 16:55:45 -0500599{
Andreas Traczyk43865372018-12-27 12:12:35 -0500600 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
601 if (!convUid.empty() && convUid == LRCInstance::getSelectedConvUid()) {
602 backToWelcomePage();
603 }
604 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, true);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400605}
606
607void CallWidget::slotIgnoreInviteClicked(const QModelIndex & index)
608{
Andreas Traczyk43865372018-12-27 12:12:35 -0500609 auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
610 if (!convUid.empty() && convUid == LRCInstance::getSelectedConvUid()) {
611 backToWelcomePage();
612 }
613 LRCInstance::getCurrentConversationModel()->removeConversation(convUid, false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400614}
615
616void CallWidget::slotCustomContextMenuRequested(const QPoint& pos)
617{
618 setupSmartListContextMenu(pos);
619}
620
Isa Nanic601de1d2018-10-23 11:37:26 -0400621void CallWidget::slotAccountChanged(int index)
622{
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500623 try {
624 auto accountList = LRCInstance::accountModel().getAccountList();
625 setSelectedAccount(accountList.at(index));
626 } catch (...) {
Andreas Traczyk43865372018-12-27 12:12:35 -0500627 qWarning() << "CallWidget::slotAccountChanged exception";
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500628 }
Isa Nanic601de1d2018-10-23 11:37:26 -0400629}
630
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400631void CallWidget::slotShowCallView(const std::string& accountId,
632 const lrc::api::conversation::Info& convInfo)
633{
634 Q_UNUSED(accountId);
635 Q_UNUSED(convInfo);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400636 qDebug() << "slotShowCallView";
Andreas Traczyk0147bf12019-01-03 20:46:03 -0500637 setCallPanelVisibility(true);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400638 ui->callStackWidget->setCurrentWidget(ui->videoPage);
Sébastien Blin93bd2062018-12-17 15:57:16 -0500639 ui->videoWidget->showChatviewIfToggled();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400640 hideMiniSpinner();
641}
642
643void CallWidget::slotShowIncomingCallView(const std::string& accountId,
Andreas Traczyk43c08232018-10-31 13:42:09 -0400644 const lrc::api::conversation::Info& convInfo)
645{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400646 Q_UNUSED(accountId);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400647 qDebug() << "slotShowIncomingCallView";
648
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400649 auto callModel = LRCInstance::getCurrentCallModel();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400650
651 if (!callModel->hasCall(convInfo.callId)) {
Nicolas Jager97a21b42015-12-03 16:55:45 -0500652 return;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400653 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500654
Andreas Traczyk43c08232018-10-31 13:42:09 -0400655 auto convModel = LRCInstance::getCurrentConversationModel();
656 ui->callerPhoto->setPixmap(QPixmap::fromImage(imageForConv(convInfo.uid)));
657 auto bestName = QString::fromStdString(Utils::bestNameForConversation(convInfo, *convModel));
658 auto bestId = QString::fromStdString(Utils::bestIdForConversation(convInfo, *convModel));
659 auto finalBestId = (bestName != bestId) ? bestId : "";
660
661 auto call = callModel->getCall(convInfo.callId);
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500662 auto isCallSelected = LRCInstance::getSelectedConvUid() == convInfo.uid;
Andreas Traczyk43c08232018-10-31 13:42:09 -0400663
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500664 auto itemInCurrentFilter = false;
Andreas Traczyk43c08232018-10-31 13:42:09 -0400665 if (call.isOutgoing) {
666 if (isCallSelected) {
667 miniSpinner_->start();
Andreas Traczyk43c08232018-10-31 13:42:09 -0400668 ui->spinnerLabel->show();
669 ui->callStackWidget->setCurrentWidget(ui->outgoingCallPage);
Andreas Traczyk0147bf12019-01-03 20:46:03 -0500670 setCallPanelVisibility(true);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400671 }
672 } else {
673 if (!QApplication::focusWidget()) {
674 auto formattedName = Utils::bestNameForConversation(convInfo, *convModel);
675 Utils::showSystemNotification(this,
676 QString(tr("Call incoming from %1")).arg(QString::fromStdString(formattedName)));
677 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400678 auto selectedAccountId = LRCInstance::getCurrentAccountInfo().id;
679 auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId);
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500680 if (!isCallSelected)
681 itemInCurrentFilter = selectSmartlistItem(convInfo.uid);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400682 if (accountProperties.autoAnswer) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400683 ui->callStackWidget->setCurrentWidget(ui->videoPage);
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500684 } else if (isCallSelected || !itemInCurrentFilter) {
Andreas Traczyk43c08232018-10-31 13:42:09 -0400685 ui->callStackWidget->setCurrentWidget(ui->incomingCallPage);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400686 }
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500687 setCallPanelVisibility(true);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400688 }
689
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500690 if (!itemInCurrentFilter && !isCallSelected) {
Andreas Traczyk3e81c1e2019-01-10 16:08:12 -0500691 if (ui->smartList->selectionModel())
692 ui->smartList->selectionModel()->clear();
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500693 LRCInstance::setSelectedConvId(convInfo.uid);
694 showChatView(accountId, convInfo);
695 } else if (ui->messagesWidget->isHidden()) {
Sébastien Blin93bd2062018-12-17 15:57:16 -0500696 ui->messagesWidget->show();
697 }
698
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400699 ui->videoWidget->pushRenderer(convInfo.callId);
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400700
Andreas Traczyk43c08232018-10-31 13:42:09 -0400701 QFontMetrics primaryCallLabelFontMetrics(ui->callingBestNameLabel->font());
702 QFontMetrics sencondaryCallLabelFontMetrics(ui->callingBestIdLabel->font());
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400703
Andreas Traczyk43c08232018-10-31 13:42:09 -0400704 QString elidedLabel = primaryCallLabelFontMetrics.elidedText(bestName, Qt::ElideRight, ui->callerBestNameLabel->width());
705 ui->callerBestNameLabel->setText(elidedLabel);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400706
Andreas Traczyk43c08232018-10-31 13:42:09 -0400707 elidedLabel = primaryCallLabelFontMetrics.elidedText(bestName, Qt::ElideRight, ui->callingBestNameLabel->width());
708 ui->callingBestNameLabel->setText(elidedLabel);
709
710 elidedLabel = sencondaryCallLabelFontMetrics.elidedText(finalBestId, Qt::ElideRight, ui->callingBestIdLabel->width());
711 ui->callingBestIdLabel->setText(elidedLabel);
712
713 ui->smartList->update();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400714}
715
716void CallWidget::slotShowChatView(const std::string& accountId,
Andreas Traczyk43c08232018-10-31 13:42:09 -0400717 const lrc::api::conversation::Info& convInfo)
718{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400719 Q_UNUSED(accountId);
720 Q_UNUSED(convInfo);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400721
Andreas Traczyk0147bf12019-01-03 20:46:03 -0500722 setCallPanelVisibility(false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400723 showConversationView();
Nicolas Jager97a21b42015-12-03 16:55:45 -0500724}
Edric Milaretab12d022015-12-04 16:09:44 -0500725
726void
Sébastien Blin93bd2062018-12-17 15:57:16 -0500727CallWidget::slotToggleFullScreenClicked()
728{
729 if (ui->mainActivityWidget->isFullScreen()) {
730 ui->stackedWidget->addWidget(ui->mainActivityWidget);
731 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
732 ui->mainActivityWidget->showNormal();
733 } else {
734 ui->stackedWidget->removeWidget(ui->mainActivityWidget);
735 ui->mainActivityWidget->setParent(0);
736 ui->mainActivityWidget->showFullScreen();
737 }
738}
739
740void
741CallWidget::slotVideoViewDestroyed(const std::string& callid)
742{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500743 auto conversation = Utils::getSelectedConversation();
Andreas Traczyk8541ffa2019-01-18 13:59:51 -0500744 if (conversation.uid.empty() || callid != conversation.callId) {
Sébastien Blin62b08ac2018-12-14 16:18:04 -0500745 return;
746 }
Sébastien Blin93bd2062018-12-17 15:57:16 -0500747 if (ui->mainActivityWidget->isFullScreen()) {
748 ui->stackedWidget->addWidget(ui->mainActivityWidget);
749 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
750 ui->mainActivityWidget->showNormal();
751 }
752 showConversationView();
753}
754
755void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400756CallWidget::setSelectedAccount(const std::string& accountId)
757{
758 LRCInstance::setSelectedAccountId(accountId);
759
760 // First, we get back to the welcome view (except if in call)
761 if (ui->stackedWidget->currentWidget() != ui->videoPage &&
762 ui->stackedWidget->currentWidget() != ui->welcomePage) {
763 Utils::setStackWidget(ui->stackedWidget, ui->welcomePage);
764 }
765
766 // We setup the ringIdLabel and the QRCode
767 auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
768 auto id = accountInfo.registeredName.empty() ? accountInfo.profileInfo.uri : accountInfo.registeredName;
769 auto isRingAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
770 if (isRingAccount) {
771 ui->ringIdLabel->setText(QString::fromStdString(id));
772 setupQRCode(QString::fromStdString(accountInfo.profileInfo.uri));
773 }
774
775 updateSmartList();
776 currentTypeFilter_ = accountInfo.profileInfo.type;
777 LRCInstance::getCurrentConversationModel()->setFilter(accountInfo.profileInfo.type);
778 updateConversationsFilterWidget();
779 connectConversationModel();
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -0500780 connectAccount(accountId);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400781}
782
783void CallWidget::setConversationFilter(lrc::api::profile::Type filter)
784{
785 if (currentTypeFilter_ == filter) {
786 return;
787 }
788 currentTypeFilter_ = filter;
789 LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
790}
791
792void CallWidget::updateConversationsFilterWidget()
793{
794 auto invites = LRCInstance::getCurrentAccountInfo().contactModel->pendingRequestCount();
795 if (invites == 0 && currentTypeFilter_ == lrc::api::profile::Type::PENDING) {
796 currentTypeFilter_ = lrc::api::profile::Type::RING;
797 LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
798 }
799 ui->conversationsFilterWidget->setVisible(invites);
Andreas Traczykdc17c812019-01-11 15:35:20 -0500800 ui->searchTopLeftWidget->setVisible(invites);
801 ui->searchTopRightWidget->setVisible(invites);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400802 ui->conversationsFilterWidget->update();
Andreas Traczykdc17c812019-01-11 15:35:20 -0500803 ui->conversationsFilterWidget->updateBadges();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400804}
805
806void CallWidget::setConversationFilter(const QString & filter)
807{
808 LRCInstance::getCurrentConversationModel()->setFilter(filter.toStdString());
Anthony Léonardd47179c2017-03-28 10:39:10 -0400809}
810
811void
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500812CallWidget::showChatView(const QModelIndex& nodeIdx)
Edric Milaretab12d022015-12-04 16:09:44 -0500813{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500814 auto convUid = nodeIdx.data(static_cast<int>(SmartListModel::Role::UID)).toString().toStdString();
815 auto convModel = LRCInstance::getCurrentConversationModel();
816 auto convInfo = Utils::getConversationFromUid(convUid, *convModel);
817 if (convInfo != convModel->allFilteredConversations().end())
818 setupChatView(*convInfo);
819}
820
821void
822CallWidget::showChatView(const std::string& accountId, const lrc::api::conversation::Info& convInfo)
823{
824 Q_UNUSED(accountId);
825 setupChatView(convInfo);
826}
827
828void
829CallWidget::setupChatView(const lrc::api::conversation::Info& convInfo)
830{
831 auto& accInfo = LRCInstance::getCurrentAccountInfo();
832 auto& contact = accInfo.contactModel->getContact(convInfo.participants.at(0));
833 QString displayName = QString::fromStdString(Utils::bestNameForContact(contact));
834 QString displayId = QString::fromStdString(Utils::bestIdForContact(contact));
835 QString contactURI = QString::fromStdString(convInfo.participants.at(0));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400836
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400837 bool isContact = false;
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500838 auto selectedAccountId = LRCInstance::getCurrAccId();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400839 auto& accountInfo = LRCInstance::accountModel().getAccountInfo(selectedAccountId);
840 bool isRINGAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
841 try {
Andreas Traczykc4e86972019-01-18 14:11:35 -0500842 auto contactInfo = accountInfo.contactModel->getContact(contactURI.toStdString());
843 if (contactInfo.isTrusted) {
844 isContact = true;
845 }
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500846 } catch (...) {}
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400847
Olivier SOLDANO31b9aac2017-07-14 15:50:09 -0400848 ui->imNameLabel->setText(QString(tr("%1", "%1 is the contact username"))
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500849 .arg(displayName));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400850
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500851 if (isRINGAccount && displayName != displayId) {
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400852 ui->imIdLabel->show();
853 ui->imIdLabel->setText(QString(tr("%1", "%1 is the contact unique identifier"))
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500854 .arg(displayId));
Olivier SOLDANO483f9682017-07-26 11:57:49 -0400855 } else {
856 ui->imIdLabel->hide();
857 }
858
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400859 bool shouldShowSendContactRequestBtn = !isContact && isRINGAccount;
Andreas Traczyk912242e2018-10-29 14:44:44 -0400860 ui->sendContactRequestButton->setVisible(shouldShowSendContactRequestBtn);
Olivier SOLDANO815d92f2017-07-13 14:05:36 -0400861
Andreas Traczykf9465492019-01-09 13:53:37 -0500862 ui->messageView->setMessagesVisibility(false);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400863 ui->messageView->clear();
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500864 ui->messageView->setInvitation(false);
Andreas Traczykf9465492019-01-09 13:53:37 -0500865 Utils::oneShotConnect(ui->messageView, &MessageWebView::messagesCleared,
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500866 [this, convInfo] {
Andreas Traczykf9465492019-01-09 13:53:37 -0500867 auto convModel = LRCInstance::getCurrentConversationModel();
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500868 ui->messageView->printHistory(*convModel, convInfo.interactions);
Andreas Traczykf9465492019-01-09 13:53:37 -0500869 Utils::oneShotConnect(ui->messageView, &MessageWebView::messagesLoaded,
870 [this] {
871 ui->messageView->setMessagesVisibility(true);
872 });
873 // Contact Avatars
874 auto accInfo = &LRCInstance::getCurrentAccountInfo();
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500875 auto contactUri = convInfo.participants.front();
Andreas Traczykf9465492019-01-09 13:53:37 -0500876 try {
877 auto& contact = accInfo->contactModel->getContact(contactUri);
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500878 auto bestName = Utils::bestNameForConversation(convInfo, *convModel);
Andreas Traczykf9465492019-01-09 13:53:37 -0500879 ui->messageView->setInvitation(
880 (contact.profileInfo.type == lrc::api::profile::Type::PENDING),
881 bestName,
882 accInfo->contactModel->getContactProfileId(contact.profileInfo.uri)
883 );
884 if (!contact.profileInfo.avatar.empty()) {
885 ui->messageView->setSenderImage(
886 accInfo->contactModel->getContactProfileId(contactUri),
887 contact.profileInfo.avatar);
888 } else {
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500889 auto avatar = Utils::conversationPhoto(convInfo.uid, *accInfo);
Andreas Traczykf9465492019-01-09 13:53:37 -0500890 QByteArray ba;
891 QBuffer bu(&ba);
892 avatar.save(&bu, "PNG");
893 std::string avatarString = ba.toBase64().toStdString();
894 ui->messageView->setSenderImage(
895 accInfo->contactModel->getContactProfileId(contactUri),
896 avatarString);
897 }
898 } catch (...) {}
899 });
Edric Milaretab12d022015-12-04 16:09:44 -0500900}
Edric Milaretfa05d972016-01-13 16:22:04 -0500901
902void
Edric Milaret8001f6f2016-01-27 09:55:12 -0500903CallWidget::on_ringContactLineEdit_textChanged(const QString& text)
Edric Milaretfa05d972016-01-13 16:22:04 -0500904{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400905 Q_UNUSED(text);
906 processContactLineEdit();
Edric Milaretfa05d972016-01-13 16:22:04 -0500907}
Edric Milareta0ebd062016-01-13 12:18:23 -0500908
Nicolas Jagerca850292016-01-17 14:11:10 -0500909void
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400910CallWidget::backToWelcomePage()
Edric Milareta0ebd062016-01-13 12:18:23 -0500911{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400912 deselectConversation();
913 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Nicolas Jagerca850292016-01-17 14:11:10 -0500914}
915
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400916void
917CallWidget::hideMiniSpinner()
Olivier SOLDANO19193412017-06-06 12:03:36 -0400918{
919 if(ui->spinnerLabel->isVisible()){
920 miniSpinner_->stop();
921 ui->spinnerLabel->hide();
922 }
923}
924
Nicolas Jagerca850292016-01-17 14:11:10 -0500925void
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400926CallWidget::on_imBackButton_clicked()
927{
Andreas Traczyk2771e2e2019-01-08 17:44:33 -0500928 ui->messageView->clear();
Andreas Traczykf9465492019-01-09 13:53:37 -0500929 Utils::oneShotConnect(ui->messageView, &MessageWebView::messagesCleared,
930 [this] {
931 QTimer::singleShot(33, this, [this] { backToWelcomePage(); });
Andreas Traczyk2771e2e2019-01-08 17:44:33 -0500932 });
Olivier SOLDANO2bcdfd72017-05-02 14:37:19 -0400933}
934
935void
Edric Milaret1e598592016-09-02 10:10:01 -0400936CallWidget::on_qrButton_toggled(bool checked)
937{
938 ui->qrLabel->setVisible(checked);
939}
940
941void
Edric Milaret4097d2f2016-02-09 14:41:50 -0500942CallWidget::on_shareButton_clicked()
943{
Sébastien Blincba5b522018-12-10 12:48:36 -0500944 Utils::InvokeMailto(tr("Contact me on Jami"), tr("My Id is : ") + ui->ringIdLabel->text());
Edric Milaret4097d2f2016-02-09 14:41:50 -0500945}
Anthony Léonardaa90e1a2016-10-12 11:24:17 -0400946
947void
Andreas Traczyk912242e2018-10-29 14:44:44 -0400948CallWidget::on_sendContactRequestButton_clicked()
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400949{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500950 auto convInfo = Utils::getSelectedConversation();
951 if (!convInfo.uid.empty()) {
952 LRCInstance::getCurrentConversationModel()->makePermanent(convInfo.uid);
953 ui->sendContactRequestButton->hide();
954 }
Olivier SOLDANOdd878662017-03-27 16:00:06 -0400955}
956
Olivier SOLDANO47aa97f2017-04-04 10:40:00 -0400957void
Andreas Traczyk912242e2018-10-29 14:44:44 -0400958CallWidget::on_btnAudioCall_clicked()
959{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500960 auto convInfo = Utils::getSelectedConversation();
961 if (!convInfo.uid.empty()) {
962 LRCInstance::getCurrentConversationModel()->placeAudioOnlyCall(convInfo.uid);
963 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convInfo.uid)));
964 }
Andreas Traczyk912242e2018-10-29 14:44:44 -0400965}
966
967void
968CallWidget::on_btnVideoCall_clicked()
969{
Andreas Traczyk1cf20c72019-01-09 19:42:32 -0500970 auto convInfo = Utils::getSelectedConversation();
971 if (!convInfo.uid.empty()) {
972 LRCInstance::getCurrentConversationModel()->placeCall(convInfo.uid);
973 ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convInfo.uid)));
974 }
Andreas Traczyk912242e2018-10-29 14:44:44 -0400975}
976
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400977bool
978CallWidget::connectConversationModel()
Anthony Léonard5cc76412017-04-21 16:52:25 -0400979{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400980 auto currentConversationModel = LRCInstance::getCurrentAccountInfo().conversationModel.get();
981
982 if (ui->smartList->selectionModel()) {
983 ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect);
Anthony Léonard5cc76412017-04-21 16:52:25 -0400984 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400985
986 QObject::disconnect(modelSortedConnection_);
987 QObject::disconnect(modelUpdatedConnection_);
988 QObject::disconnect(filterChangedConnection_);
989 QObject::disconnect(newConversationConnection_);
990 QObject::disconnect(conversationRemovedConnection_);
991 QObject::disconnect(conversationClearedConnection);
992 QObject::disconnect(interactionStatusUpdatedConnection_);
993 QObject::disconnect(newInteractionConnection_);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400994 QObject::disconnect(interactionRemovedConnection_);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400995
996 modelSortedConnection_ = QObject::connect(
997 currentConversationModel, &lrc::api::ConversationModel::modelSorted,
998 [this]() {
999 updateConversationsFilterWidget();
Andreas Traczyk1cf20c72019-01-09 19:42:32 -05001000 selectSmartlistItem(Utils::getSelectedConversation().uid);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001001 ui->smartList->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001002 }
1003 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001004 modelUpdatedConnection_ = QObject::connect(
1005 currentConversationModel, &lrc::api::ConversationModel::conversationUpdated,
1006 [this](const std::string& convUid) {
1007 Q_UNUSED(convUid);
1008 ui->smartList->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001009 }
1010 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001011 filterChangedConnection_ = QObject::connect(
1012 currentConversationModel, &lrc::api::ConversationModel::filterChanged,
1013 [this]() {
1014 updateSmartList();
1015 updateConversationsFilterWidget();
1016 ui->smartList->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001017 }
1018 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001019 newConversationConnection_ = QObject::connect(
1020 currentConversationModel, &lrc::api::ConversationModel::newConversation,
1021 [this](const std::string& convUid) {
1022 updateSmartList();
1023 updateConversationForNewContact(convUid);
1024 ui->conversationsFilterWidget->update();
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001025 }
1026 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001027 conversationRemovedConnection_ = QObject::connect(
1028 currentConversationModel, &lrc::api::ConversationModel::conversationRemoved,
1029 [this]() {
1030 backToWelcomePage();
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001031 }
1032 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001033 conversationClearedConnection = QObject::connect(
1034 currentConversationModel, &lrc::api::ConversationModel::conversationCleared,
1035 [this](const std::string& convUid) {
Andreas Traczyk43c08232018-10-31 13:42:09 -04001036 ui->messageView->clear();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001037 // if currently selected,
1038 // switch to welcome screen (deselecting current smartlist item )
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001039 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001040 return;
1041 }
1042 backToWelcomePage();
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001043 }
1044 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001045 interactionStatusUpdatedConnection_ = QObject::connect(
1046 currentConversationModel, &lrc::api::ConversationModel::interactionStatusUpdated,
Andreas Traczyk43c08232018-10-31 13:42:09 -04001047 [this](const std::string& convUid, uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001048 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001049 return;
1050 }
Andreas Traczyk43c08232018-10-31 13:42:09 -04001051 auto& currentAccountInfo = LRCInstance::getCurrentAccountInfo();
1052 auto currentConversationModel = currentAccountInfo.conversationModel.get();
1053 currentConversationModel->clearUnreadInteractions(convUid);
1054 ui->conversationsFilterWidget->update();
1055 ui->messageView->updateInteraction(*currentConversationModel, interactionId, interaction);
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001056 }
1057 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001058 newInteractionConnection_ = QObject::connect(
1059 currentConversationModel, &lrc::api::ConversationModel::newInteraction,
1060 [this](const std::string& convUid, uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
1061 onIncomingMessage(convUid, interactionId, interaction);
Andreas Traczyk4b4bfde2018-12-19 09:53:22 -05001062 if (interaction.type == lrc::api::interaction::Type::CALL) {
1063 return;
1064 }
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001065 if (convUid == LRCInstance::getSelectedConvUid()) {
Andreas Traczyk4b4bfde2018-12-19 09:53:22 -05001066 ui->videoWidget->simulateShowChatview(true);
1067 }
Isa Nanic37ccc1c2018-10-26 14:16:28 -04001068 }
1069 );
Andreas Traczyk43c08232018-10-31 13:42:09 -04001070 interactionRemovedConnection_ = QObject::connect(
1071 currentConversationModel, &lrc::api::ConversationModel::interactionRemoved,
1072 [this](const std::string& convUid, uint64_t interactionId) {
1073 Q_UNUSED(convUid);
1074 ui->messageView->removeInteraction(interactionId);
1075 }
1076 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001077 currentConversationModel->setFilter("");
1078 // clear search field
1079 ui->ringContactLineEdit->setText("");
1080 return true;
1081}
1082
1083void
1084CallWidget::updateConversationView(const std::string& convUid)
1085{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001086 if (convUid != LRCInstance::getSelectedConvUid()) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001087 return;
1088 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001089}
1090
1091void
1092CallWidget::selectConversation(const QModelIndex& index)
1093{
1094 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
1095
1096 if (currentConversationModel == nullptr || !index.isValid()) {
1097 return;
1098 }
1099
1100 const auto item = currentConversationModel->filteredConversation(index.row());
1101
1102 if (selectConversation(item, *currentConversationModel)) {
Andreas Traczyk1cf20c72019-01-09 19:42:32 -05001103 showChatView(index);
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001104 auto convUid = LRCInstance::getSelectedConvUid();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001105 if (!lastConvUid_.compare(convUid)) {
1106 return;
1107 }
1108 lastConvUid_.assign(convUid);
1109 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
1110 auto callModel = LRCInstance::getCurrentCallModel();
1111 auto conversation = Utils::getConversationFromUid(convUid, *currentConversationModel);
1112 const auto item = currentConversationModel->filteredConversation(index.row());
Andreas Traczyk43c08232018-10-31 13:42:09 -04001113 if (callModel->hasCall(conversation->callId) && item.callId == conversation->callId) {
Andreas Traczyk0147bf12019-01-03 20:46:03 -05001114 setCallPanelVisibility(true);
Andreas Traczyk43c08232018-10-31 13:42:09 -04001115 return;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001116 }
Andreas Traczyk0147bf12019-01-03 20:46:03 -05001117 setCallPanelVisibility(false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001118 }
Anthony Léonard5cc76412017-04-21 16:52:25 -04001119}
Anthony Léonardecfe7422017-05-04 14:14:37 -04001120
Anthony Léonard041ad392017-07-14 16:44:09 -04001121bool
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001122CallWidget::selectConversation( const lrc::api::conversation::Info& item,
1123 lrc::api::ConversationModel& convModel)
Anthony Léonard041ad392017-07-14 16:44:09 -04001124{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001125 if (LRCInstance::getSelectedConvUid() == item.uid) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001126 return false;
1127 } else if (item.participants.size() > 0) {
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001128 LRCInstance::setSelectedConvId(item.uid);
Andreas Traczyk1cf20c72019-01-09 19:42:32 -05001129 convModel.selectConversation(item.uid);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001130 convModel.clearUnreadInteractions(item.uid);
1131 ui->conversationsFilterWidget->update();
1132 return true;
Anthony Léonard041ad392017-07-14 16:44:09 -04001133 }
Anthony Léonard041ad392017-07-14 16:44:09 -04001134}
1135
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001136void
1137CallWidget::deselectConversation()
Anthony Léonardecfe7422017-05-04 14:14:37 -04001138{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001139 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
1140
1141 if (currentConversationModel == nullptr) {
1142 return;
1143 }
1144
1145 currentConversationModel->selectConversation("");
1146 LRCInstance::setSelectedConvId("");
1147
1148 ui->smartList->selectionModel()->clear();
1149 disconnect(imConnection_);
Anthony Léonardecfe7422017-05-04 14:14:37 -04001150}
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001151
1152void
1153CallWidget::updateConversationForNewContact(const std::string& convUid)
1154{
1155 auto convModel = LRCInstance::getCurrentConversationModel();
1156 if (convModel == nullptr) {
1157 return;
1158 }
1159 ui->ringContactLineEdit->setText("");
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001160 auto selectedUid = LRCInstance::getSelectedConvUid();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001161 auto it = Utils::getConversationFromUid(convUid, *convModel);
1162 if (it != convModel->allFilteredConversations().end()) {
1163 try {
1164 auto contact = convModel->owner.contactModel->getContact(it->participants[0]);
1165 if (!contact.profileInfo.uri.empty() && contact.profileInfo.uri.compare(selectedUid) == 0) {
1166 LRCInstance::setSelectedConvId(convUid);
1167 convModel->selectConversation(convUid);
1168 }
1169 } catch (...) {
1170 return;
1171 }
1172 }
1173}
1174
1175void
1176CallWidget::updateSmartList()
1177{
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001178 if (!ui->smartList->model()) {
1179 smartListModel_.reset(new SmartListModel(LRCInstance::getCurrAccId(), this));
1180 ui->smartList->setModel(smartListModel_.get());
1181 ui->smartList->setItemDelegate(new ConversationItemDelegate());
1182 } else {
1183 smartListModel_->setAccount(LRCInstance::getCurrAccId());
1184 }
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001185
1186 // smartlist selection
1187 QObject::disconnect(smartlistSelectionConnection_);
1188 smartlistSelectionConnection_ = connect(ui->smartList->selectionModel(),
1189 SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
1190 this,
1191 SLOT(smartListSelectionChanged(QItemSelection, QItemSelection)));
1192}
1193
1194void
Isa Nanic6e4a39a2018-12-04 14:26:02 -05001195CallWidget::updateComboBox()
1196{
1197 ui->currentAccountComboBox->updateComboBoxDisplay();
1198}
1199
1200void
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001201CallWidget::update()
1202{
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001203 updateSmartList();
1204 updateConversationsFilterWidget();
Isa Nanic6e4a39a2018-12-04 14:26:02 -05001205 updateComboBox();
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001206 connectConversationModel();
Isa Nanic601de1d2018-10-23 11:37:26 -04001207}
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001208
1209void
1210CallWidget::connectAccount(const std::string& accId)
1211{
1212 auto callModel = LRCInstance::accountModel().getAccountInfo(accId).callModel.get();
1213 disconnect(callStatusChangedConnection_);
1214 callStatusChangedConnection_ = QObject::connect(callModel, &lrc::api::NewCallModel::callStatusChanged,
1215 [this, accId](const std::string& callId) {
1216 auto callModel = LRCInstance::accountModel().getAccountInfo(accId).callModel.get();
1217 auto call = callModel->getCall(callId);
1218 switch (call.status) {
1219 case lrc::api::call::Status::INVALID:
1220 case lrc::api::call::Status::INACTIVE:
1221 case lrc::api::call::Status::ENDED:
1222 case lrc::api::call::Status::PEER_BUSY:
1223 case lrc::api::call::Status::TIMEOUT:
1224 case lrc::api::call::Status::TERMINATING:
1225 {
Andreas Traczyk0147bf12019-01-03 20:46:03 -05001226 setCallPanelVisibility(false);
Andreas Traczyk6b5ad3e2019-01-02 17:04:36 -05001227 showConversationView();
1228 break;
1229 }
1230 default:
1231 break;
1232 }
1233 });
1234 auto& contactModel = LRCInstance::getCurrentAccountInfo().contactModel;
1235 disconnect(contactAddedConnection_);
1236 contactAddedConnection_ = connect(contactModel.get(), &lrc::api::ContactModel::contactAdded,
1237 [this, &contactModel](const std::string & contactId) {
1238 auto convModel = LRCInstance::getCurrentConversationModel();
1239 auto currentConversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(),
1240 *convModel);
1241 if (currentConversation == convModel->allFilteredConversations().end()) {
1242 return;
1243 }
1244 if (contactId == contactModel.get()->getContact((*currentConversation).participants.at(0)).profileInfo.uri) {
1245 ui->messageView->clear();
1246 ui->messageView->printHistory(*convModel, currentConversation->interactions);
1247 }
1248 });
Andreas Traczyk39fa4d02019-01-03 17:32:07 -05001249}
1250
1251void
Andreas Traczyk0147bf12019-01-03 20:46:03 -05001252CallWidget::setCallPanelVisibility(bool visible)
Andreas Traczyk39fa4d02019-01-03 17:32:07 -05001253{
1254 ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget);
Andreas Traczyk0147bf12019-01-03 20:46:03 -05001255 ui->imBackButton->setVisible(!visible);
1256 ui->btnAudioCall->setVisible(!visible);
1257 ui->btnVideoCall->setVisible(!visible);
Andreas Traczyk2771e2e2019-01-08 17:44:33 -05001258 ui->callStackWidget->setVisible(visible);
Andreas Traczyk39fa4d02019-01-03 17:32:07 -05001259}