diff --git a/callwidget.cpp b/callwidget.cpp index a4b7da8fc4f0c8d314f7549ed5eb359f3e1247e0..99c5359f1078e38ea9ff2fbb7a88819ff1125757 100644 --- a/callwidget.cpp +++ b/callwidget.cpp @@ -302,11 +302,10 @@ CallWidget::onIncomingMessage(const std::string& convUid, auto convModel = LRCInstance::getCurrentConversationModel(); convModel->clearUnreadInteractions(convUid); - auto currentConversation = Utils::getConversationFromUid(convUid, *convModel); - if (currentConversation == convModel->allFilteredConversations().end()) { - return; + auto convInfo = Utils::getSelectedConversation(); + if (!convInfo.uid.empty()) { + ui->messageView->printNewInteraction(*convModel, interactionId, interaction); } - ui->messageView->printNewInteraction(*convModel, interactionId, interaction); } void @@ -447,33 +446,35 @@ CallWidget::on_smartList_clicked(const QModelIndex& index) void CallWidget::on_acceptButton_clicked() { - auto convModel = LRCInstance::getCurrentConversationModel(); - auto callModel = LRCInstance::getCurrentCallModel(); - auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); - callModel->accept(conversation->callId); + auto convInfo = Utils::getSelectedConversation(); + if (!convInfo.uid.empty()) { + LRCInstance::getCurrentCallModel()->accept(convInfo.callId); + } } void CallWidget::on_refuseButton_clicked() { - auto convModel = LRCInstance::getCurrentConversationModel(); - auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); - LRCInstance::getCurrentCallModel()->hangUp(conversation->callId); - showConversationView(); + auto convInfo = Utils::getSelectedConversation(); + if (!convInfo.uid.empty()) { + LRCInstance::getCurrentCallModel()->hangUp(convInfo.callId); + showConversationView(); + } } void CallWidget::on_cancelButton_clicked() { - auto convModel = LRCInstance::getCurrentConversationModel(); - auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); - LRCInstance::getCurrentCallModel()->hangUp(conversation->callId); - showConversationView(); + on_refuseButton_clicked(); } void CallWidget::showConversationView() { + if (LRCInstance::getSelectedConvUid().empty()) { + backToWelcomePage(); + return; + } ui->stackedWidget->setCurrentWidget(ui->mainActivityWidget); ui->messageView->setFocus(); if (ui->messagesWidget->isHidden()) { @@ -481,30 +482,31 @@ CallWidget::showConversationView() } } -void +bool CallWidget::selectSmartlistItem(const std::string & convUid) { if (convUid.empty() || !ui->smartList->selectionModel()) - return; + return false; ui->smartList->selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Deselect); auto convModel = LRCInstance::getCurrentConversationModel(); auto conversation = Utils::getConversationFromUid(convUid, *convModel); if (conversation == convModel->allFilteredConversations().end()) { - return; + return false; } auto contactURI = QString::fromStdString((*conversation).participants[0]); if (contactURI.isEmpty() || convModel->owner.contactModel->getContact(contactURI.toStdString()).profileInfo.type == lrc::api::profile::Type::TEMPORARY) { - return; + return false; } for (int row = 0; row < smartListModel_->rowCount(); row++) { QModelIndex index = smartListModel_->index(row); auto indexContactURI = index.data(SmartListModel::Role::URI).value<QString>(); if (indexContactURI == contactURI) { ui->smartList->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); - return; + return true; } } + return false; } void @@ -513,6 +515,8 @@ CallWidget::on_smartList_doubleClicked(const QModelIndex& index) if (!index.isValid()) return; + selectConversation(index); + LRCInstance::getCurrentConversationModel()->placeCall(LRCInstance::getSelectedConvUid()); ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(LRCInstance::getSelectedConvUid()))); @@ -673,6 +677,7 @@ void CallWidget::slotShowIncomingCallView(const std::string& accountId, auto call = callModel->getCall(convInfo.callId); auto isCallSelected = LRCInstance::getSelectedConvUid() == convInfo.uid; + auto itemInCurrentFilter = false; if (call.isOutgoing) { if (isCallSelected) { miniSpinner_->start(); @@ -686,19 +691,23 @@ void CallWidget::slotShowIncomingCallView(const std::string& accountId, Utils::showSystemNotification(this, QString(tr("Call incoming from %1")).arg(QString::fromStdString(formattedName))); } - selectSmartlistItem(convInfo.uid); auto selectedAccountId = LRCInstance::getCurrentAccountInfo().id; auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId); + if (!isCallSelected) + itemInCurrentFilter = selectSmartlistItem(convInfo.uid); if (accountProperties.autoAnswer) { ui->callStackWidget->setCurrentWidget(ui->videoPage); - setCallPanelVisibility(true); - } else if (isCallSelected) { + } else if (isCallSelected || !itemInCurrentFilter) { ui->callStackWidget->setCurrentWidget(ui->incomingCallPage); - setCallPanelVisibility(true); } + setCallPanelVisibility(true); } - if (ui->messagesWidget->isHidden()) { + if (!itemInCurrentFilter && !isCallSelected) { + ui->smartList->selectionModel()->clear(); + LRCInstance::setSelectedConvId(convInfo.uid); + showChatView(accountId, convInfo); + } else if (ui->messagesWidget->isHidden()) { ui->messagesWidget->show(); } @@ -746,11 +755,8 @@ CallWidget::slotToggleFullScreenClicked() void CallWidget::slotVideoViewDestroyed(const std::string& callid) { - auto convUid = LRCInstance::getSelectedConvUid(); - auto currentConversationModel = LRCInstance::getCurrentConversationModel(); - auto conversation = Utils::getConversationFromUid(convUid, *currentConversationModel); - if (conversation != currentConversationModel->allFilteredConversations().end() && - callid != conversation->callId) { + auto conversation = Utils::getSelectedConversation(); + if (callid != conversation.uid) { return; } if (ui->mainActivityWidget->isFullScreen()) { @@ -816,11 +822,30 @@ void CallWidget::setConversationFilter(const QString & filter) } void -CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx) +CallWidget::showChatView(const QModelIndex& nodeIdx) +{ + auto convUid = nodeIdx.data(static_cast<int>(SmartListModel::Role::UID)).toString().toStdString(); + auto convModel = LRCInstance::getCurrentConversationModel(); + auto convInfo = Utils::getConversationFromUid(convUid, *convModel); + if (convInfo != convModel->allFilteredConversations().end()) + setupChatView(*convInfo); +} + +void +CallWidget::showChatView(const std::string& accountId, const lrc::api::conversation::Info& convInfo) { - QString displayName = nodeIdx.data(static_cast<int>(SmartListModel::Role::DisplayName)).toString(); - QString displayId = nodeIdx.data(static_cast<int>(SmartListModel::Role::DisplayID)).toString(); - QString contactURI = nodeIdx.data(static_cast<int>(SmartListModel::Role::URI)).toString(); + Q_UNUSED(accountId); + setupChatView(convInfo); +} + +void +CallWidget::setupChatView(const lrc::api::conversation::Info& convInfo) +{ + auto& accInfo = LRCInstance::getCurrentAccountInfo(); + auto& contact = accInfo.contactModel->getContact(convInfo.participants.at(0)); + QString displayName = QString::fromStdString(Utils::bestNameForContact(contact)); + QString displayId = QString::fromStdString(Utils::bestIdForContact(contact)); + QString contactURI = QString::fromStdString(convInfo.participants.at(0)); bool isContact = false; auto selectedAccountId = LRCInstance::getCurrAccId(); @@ -829,16 +854,15 @@ CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx) try { accountInfo.contactModel->getContact(contactURI.toStdString()); isContact = true; - } - catch (...) {} + } catch (...) {} ui->imNameLabel->setText(QString(tr("%1", "%1 is the contact username")) - .arg(displayName)); + .arg(displayName)); - if (isRINGAccount && displayName != displayId){ + if (isRINGAccount && displayName != displayId) { ui->imIdLabel->show(); ui->imIdLabel->setText(QString(tr("%1", "%1 is the contact unique identifier")) - .arg(displayId)); + .arg(displayId)); } else { ui->imIdLabel->hide(); } @@ -848,22 +872,21 @@ CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx) ui->messageView->setMessagesVisibility(false); ui->messageView->clear(); + ui->messageView->setInvitation(false); Utils::oneShotConnect(ui->messageView, &MessageWebView::messagesCleared, - [this] { + [this, convInfo] { auto convModel = LRCInstance::getCurrentConversationModel(); - auto currentConversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), - *convModel); - ui->messageView->printHistory(*convModel, currentConversation->interactions); + ui->messageView->printHistory(*convModel, convInfo.interactions); Utils::oneShotConnect(ui->messageView, &MessageWebView::messagesLoaded, [this] { ui->messageView->setMessagesVisibility(true); }); // Contact Avatars auto accInfo = &LRCInstance::getCurrentAccountInfo(); - auto contactUri = currentConversation->participants.front(); + auto contactUri = convInfo.participants.front(); try { auto& contact = accInfo->contactModel->getContact(contactUri); - auto bestName = Utils::bestNameForConversation(*currentConversation, *convModel); + auto bestName = Utils::bestNameForConversation(convInfo, *convModel); ui->messageView->setInvitation( (contact.profileInfo.type == lrc::api::profile::Type::PENDING), bestName, @@ -874,7 +897,7 @@ CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx) accInfo->contactModel->getContactProfileId(contactUri), contact.profileInfo.avatar); } else { - auto avatar = Utils::conversationPhoto(LRCInstance::getSelectedConvUid(), *accInfo); + auto avatar = Utils::conversationPhoto(convInfo.uid, *accInfo); QByteArray ba; QBuffer bu(&ba); avatar.save(&bu, "PNG"); @@ -935,24 +958,31 @@ CallWidget::on_shareButton_clicked() void CallWidget::on_sendContactRequestButton_clicked() { - LRCInstance::getCurrentConversationModel()->makePermanent(LRCInstance::getSelectedConvUid()); - ui->sendContactRequestButton->hide(); + auto convInfo = Utils::getSelectedConversation(); + if (!convInfo.uid.empty()) { + LRCInstance::getCurrentConversationModel()->makePermanent(convInfo.uid); + ui->sendContactRequestButton->hide(); + } } void CallWidget::on_btnAudioCall_clicked() { - auto convUid = LRCInstance::getSelectedConvUid(); - LRCInstance::getCurrentConversationModel()->placeAudioOnlyCall(convUid); - ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid))); + auto convInfo = Utils::getSelectedConversation(); + if (!convInfo.uid.empty()) { + LRCInstance::getCurrentConversationModel()->placeAudioOnlyCall(convInfo.uid); + ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convInfo.uid))); + } } void CallWidget::on_btnVideoCall_clicked() { - auto convUid = LRCInstance::getSelectedConvUid(); - LRCInstance::getCurrentConversationModel()->placeCall(convUid); - ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid))); + auto convInfo = Utils::getSelectedConversation(); + if (!convInfo.uid.empty()) { + LRCInstance::getCurrentConversationModel()->placeCall(convInfo.uid); + ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convInfo.uid))); + } } bool @@ -978,7 +1008,7 @@ CallWidget::connectConversationModel() currentConversationModel, &lrc::api::ConversationModel::modelSorted, [this]() { updateConversationsFilterWidget(); - selectSmartlistItem(LRCInstance::getSelectedConvUid()); + selectSmartlistItem(Utils::getSelectedConversation().uid); ui->smartList->update(); } ); @@ -1081,7 +1111,7 @@ CallWidget::selectConversation(const QModelIndex& index) const auto item = currentConversationModel->filteredConversation(index.row()); if (selectConversation(item, *currentConversationModel)) { - showIMOutOfCall(index); + showChatView(index); auto convUid = LRCInstance::getSelectedConvUid(); if (!lastConvUid_.compare(convUid)) { return; @@ -1106,8 +1136,8 @@ CallWidget::selectConversation( const lrc::api::conversation::Info& item, if (LRCInstance::getSelectedConvUid() == item.uid) { return false; } else if (item.participants.size() > 0) { - convModel.selectConversation(item.uid); LRCInstance::setSelectedConvId(item.uid); + convModel.selectConversation(item.uid); convModel.clearUnreadInteractions(item.uid); ui->conversationsFilterWidget->update(); return true; diff --git a/callwidget.h b/callwidget.h index edc3e86100de2dc1a7f4c869e4f99a07bcef5217..54365b97382e1b18c36a694f11aed3b3ba62ed8d 100644 --- a/callwidget.h +++ b/callwidget.h @@ -75,7 +75,9 @@ public slots: public slots: void settingsButtonClicked(); - void showIMOutOfCall(const QModelIndex& nodeIdx); + void showChatView(const QModelIndex& nodeIdx); + void showChatView(const std::string & accountId, const lrc::api::conversation::Info & convInfo); + void setupChatView(const lrc::api::conversation::Info& convInfo); void slotAcceptInviteClicked(const QModelIndex& index); void slotBlockInviteClicked(const QModelIndex& index); void slotIgnoreInviteClicked(const QModelIndex& index); @@ -121,7 +123,7 @@ private: bool connectConversationModel(); void updateConversationView(const std::string& convUid); void showConversationView(); - void selectSmartlistItem(const std::string& convUid); + bool selectSmartlistItem(const std::string& convUid); QImage imageForConv(const std::string & convUid); void processContactLineEdit(); void hideMiniSpinner(); diff --git a/utils.cpp b/utils.cpp index 8828b023255625e31b9aac84af21d80c81d3dae3..381fc32f9ed7e4888595ba44e988e38b07dfcbb7 100644 --- a/utils.cpp +++ b/utils.cpp @@ -395,14 +395,13 @@ Utils::isContactValid(const std::string& contactUid, const lrc::api::Conversatio QImage Utils::conversationPhoto(const std::string & convUid, const lrc::api::account::Info& accountInfo) { - auto& convModel = accountInfo.conversationModel; - auto conversation = Utils::getConversationFromUid(convUid, *convModel); - if (conversation == (*convModel).allFilteredConversations().end()) { - return QImage(); + auto convInfo = getConversationFromUid(convUid, false); + if (!convInfo.uid.empty()) { + return GlobalInstances::pixmapManipulator() + .decorationRole(convInfo, accountInfo) + .value<QImage>(); } - - QVariant var = GlobalInstances::pixmapManipulator().decorationRole(*conversation, accountInfo); - return var.value<QImage>(); + return QImage(); } QByteArray @@ -444,3 +443,32 @@ Utils::getConversationFromCallId(const std::string& callId) } return ""; } + +lrc::api::conversation::Info +Utils::getSelectedConversation() +{ + return getConversationFromUid(LRCInstance::getSelectedConvUid(), false); +} + +lrc::api::conversation::Info +Utils::getConversationFromUid(const std::string & convUid, bool filtered) +{ + auto convModel = LRCInstance::getCurrentConversationModel(); + if (filtered) { + auto conversation = getConversationFromUid(convUid, *convModel); + } else { + using namespace lrc::api::profile; + for (int i = toUnderlyingValue(Type::RING); i <= toUnderlyingValue(Type::TEMPORARY); ++i) { + auto filter = toEnum<lrc::api::profile::Type>(i); + auto conversations = convModel->getFilteredConversations(filter); + auto conv = std::find_if(conversations.begin(), conversations.end(), + [&](const lrc::api::conversation::Info& conv) { + return convUid == conv.uid; + }); + if (conv != conversations.end()) { + return *conv; + } + } + } + return lrc::api::conversation::Info(); +} diff --git a/utils.h b/utils.h index 25665f7a90d18c7c1eff9b22398ac85949dc8712..c2d79c9744bb9b0fee621f335a704077b7068458 100644 --- a/utils.h +++ b/utils.h @@ -79,6 +79,8 @@ namespace Utils QByteArray QByteArrayFromFile(const QString& filename); QPixmap generateTintedPixmap(const QString& filename, QColor color); std::string getConversationFromCallId(const std::string& callId); + lrc::api::conversation::Info getSelectedConversation(); + lrc::api::conversation::Info getConversationFromUid(const std::string & convUid, bool filtered = true); template <typename Func1, typename Func2> void