diff --git a/callwidget.cpp b/callwidget.cpp index 8cac5a0b1d4eccd60604bb87192dedfa17064f88..65285938d3d4be28ec5736958bc3f67b7b8209cb 100644 --- a/callwidget.cpp +++ b/callwidget.cpp @@ -276,7 +276,7 @@ CallWidget::onIncomingMessage(const std::string& convUid, .arg(QString::fromStdString(bestName))); } updateConversationsFilterWidget(); - if (convUid != selectedConvUid()) { + if (convUid != LRCInstance::getSelectedConvUid()) { return; } @@ -319,7 +319,7 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos) [this, convUid, conversation, convModel]() { convModel->placeCall(convUid); ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid))); - if (convUid != selectedConvUid()) { + if (convUid != LRCInstance::getSelectedConvUid()) { selectConversation(*conversation, *convModel); } }); @@ -330,7 +330,7 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos) [this, convUid, conversation, convModel]() { convModel->placeAudioOnlyCall(convUid); ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(convUid))); - if (convUid != selectedConvUid()) { + if (convUid != LRCInstance::getSelectedConvUid()) { selectConversation(*conversation, *convModel); } }); @@ -429,7 +429,7 @@ CallWidget::on_acceptButton_clicked() { auto convModel = LRCInstance::getCurrentConversationModel(); auto callModel = LRCInstance::getCurrentCallModel(); - auto conversation = Utils::getConversationFromUid(selectedConvUid(), *convModel); + auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); callModel->accept(conversation->callId); } @@ -437,7 +437,7 @@ void CallWidget::on_refuseButton_clicked() { auto convModel = LRCInstance::getCurrentConversationModel(); - auto conversation = Utils::getConversationFromUid(selectedConvUid(), *convModel); + auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); LRCInstance::getCurrentCallModel()->hangUp(conversation->callId); showConversationView(); } @@ -446,7 +446,7 @@ void CallWidget::on_cancelButton_clicked() { auto convModel = LRCInstance::getCurrentConversationModel(); - auto conversation = Utils::getConversationFromUid(selectedConvUid(), *convModel); + auto conversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); LRCInstance::getCurrentCallModel()->hangUp(conversation->callId); showConversationView(); } @@ -494,9 +494,9 @@ CallWidget::on_smartList_doubleClicked(const QModelIndex& index) if (!index.isValid()) return; - LRCInstance::getCurrentConversationModel()->placeCall(selectedConvUid()); + LRCInstance::getCurrentConversationModel()->placeCall(LRCInstance::getSelectedConvUid()); - ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(selectedConvUid()))); + ui->callingPhoto->setPixmap(QPixmap::fromImage(imageForConv(LRCInstance::getSelectedConvUid()))); } QImage @@ -505,18 +505,6 @@ CallWidget::imageForConv(const std::string& convUid) return Utils::conversationPhoto(convUid, LRCInstance::getCurrentAccountInfo()); } -const std::string& -CallWidget::selectedAccountId() -{ - return LRCInstance::getCurrAccId(); -} - -const std::string& -CallWidget::selectedConvUid() -{ - return LRCInstance::getSelectedConvUid(); -} - void CallWidget::smartListSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { @@ -628,21 +616,6 @@ void CallWidget::slotAccountChanged(int index) try { auto accountList = LRCInstance::accountModel().getAccountList(); setSelectedAccount(accountList.at(index)); - auto& contactModel = LRCInstance::getCurrentAccountInfo().contactModel; - disconnect(contactAddedConnection_); - contactAddedConnection_ = connect(contactModel.get(), &lrc::api::ContactModel::contactAdded, - [this, &contactModel](const std::string & contactId) { - auto convModel = LRCInstance::getCurrentConversationModel(); - auto currentConversation = Utils::getConversationFromUid(selectedConvUid(), - *convModel); - if (currentConversation == convModel->allFilteredConversations().end()) { - return; - } - if (contactId == contactModel.get()->getContact((*currentConversation).participants.at(0)).profileInfo.uri) { - ui->messageView->clear(); - ui->messageView->printHistory(*convModel, currentConversation->interactions); - } - }); } catch (...) { qWarning() << "CallWidget::slotAccountChanged exception"; } @@ -679,7 +652,7 @@ void CallWidget::slotShowIncomingCallView(const std::string& accountId, auto finalBestId = (bestName != bestId) ? bestId : ""; auto call = callModel->getCall(convInfo.callId); - auto isCallSelected = selectedConvUid() == convInfo.uid; + auto isCallSelected = LRCInstance::getSelectedConvUid() == convInfo.uid; if (call.isOutgoing) { if (isCallSelected) { @@ -712,22 +685,6 @@ void CallWidget::slotShowIncomingCallView(const std::string& accountId, ui->messagesWidget->show(); } - // flashing index widget during call - for (int row = 0; row < smartListModel_->rowCount(); row++) { - QModelIndex index = smartListModel_->index(row); - auto indexUid = index.data(SmartListModel::Role::UID).value<QString>().toStdString(); - if (indexUid == convInfo.uid) { - auto widget = ui->smartList->indexWidget(index); - if (!widget) { - auto blinkingWidget = new AnimatedOverlay(RingTheme::urgentOrange_); - ui->smartList->setIndexWidget(index, blinkingWidget); - blinkingWidget->show(); - } else { - widget->show(); - } - } - } - ui->videoWidget->pushRenderer(convInfo.callId); QFontMetrics primaryCallLabelFontMetrics(ui->callingBestNameLabel->font()); @@ -751,18 +708,6 @@ void CallWidget::slotShowChatView(const std::string& accountId, Q_UNUSED(accountId); Q_UNUSED(convInfo); - for (int row = 0; row < smartListModel_->rowCount(); row++) { - QModelIndex index = smartListModel_->index(row); - auto indexUid = index.data(SmartListModel::Role::UID).value<QString>().toStdString(); - if (indexUid == convInfo.uid) { - if (auto widget = ui->smartList->indexWidget(index)) { - widget->hide(); - widget->deleteLater(); - ui->smartList->setIndexWidget(index, nullptr); - } - } - } - ui->callStackWidget->hide(); showConversationView(); } @@ -824,6 +769,7 @@ CallWidget::setSelectedAccount(const std::string& accountId) LRCInstance::getCurrentConversationModel()->setFilter(accountInfo.profileInfo.type); updateConversationsFilterWidget(); connectConversationModel(); + connectAccount(accountId); } void CallWidget::setConversationFilter(lrc::api::profile::Type filter) @@ -884,7 +830,7 @@ CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx) ui->sendContactRequestButton->setVisible(shouldShowSendContactRequestBtn); auto convModel = LRCInstance::getCurrentConversationModel(); - auto currentConversation = Utils::getConversationFromUid(selectedConvUid(), + auto currentConversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), *convModel); ui->messageView->clear(); ui->messageView->printHistory(*convModel, currentConversation->interactions, true); @@ -905,7 +851,7 @@ CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx) accInfo->contactModel->getContactProfileId(contactUri), contact.profileInfo.avatar); } else { - auto avatar = Utils::conversationPhoto(selectedConvUid(), *accInfo); + auto avatar = Utils::conversationPhoto(LRCInstance::getSelectedConvUid(), *accInfo); QByteArray ba; QBuffer bu(&ba); avatar.save(&bu, "PNG"); @@ -962,7 +908,7 @@ CallWidget::on_shareButton_clicked() void CallWidget::on_sendContactRequestButton_clicked() { - LRCInstance::getCurrentConversationModel()->makePermanent(selectedConvUid()); + LRCInstance::getCurrentConversationModel()->makePermanent(LRCInstance::getSelectedConvUid()); ui->sendContactRequestButton->hide(); } @@ -1005,7 +951,7 @@ CallWidget::connectConversationModel() currentConversationModel, &lrc::api::ConversationModel::modelSorted, [this]() { updateConversationsFilterWidget(); - selectSmartlistItem(selectedConvUid()); + selectSmartlistItem(LRCInstance::getSelectedConvUid()); ui->smartList->update(); } ); @@ -1044,7 +990,7 @@ CallWidget::connectConversationModel() ui->messageView->clear(); // if currently selected, // switch to welcome screen (deselecting current smartlist item ) - if (convUid != selectedConvUid()) { + if (convUid != LRCInstance::getSelectedConvUid()) { return; } backToWelcomePage(); @@ -1053,7 +999,7 @@ CallWidget::connectConversationModel() interactionStatusUpdatedConnection_ = QObject::connect( currentConversationModel, &lrc::api::ConversationModel::interactionStatusUpdated, [this](const std::string& convUid, uint64_t interactionId, const lrc::api::interaction::Info& interaction) { - if (convUid != selectedConvUid()) { + if (convUid != LRCInstance::getSelectedConvUid()) { return; } auto& currentAccountInfo = LRCInstance::getCurrentAccountInfo(); @@ -1070,7 +1016,7 @@ CallWidget::connectConversationModel() if (interaction.type == lrc::api::interaction::Type::CALL) { return; } - if (convUid == selectedConvUid()) { + if (convUid == LRCInstance::getSelectedConvUid()) { ui->videoWidget->simulateShowChatview(true); } } @@ -1091,7 +1037,7 @@ CallWidget::connectConversationModel() void CallWidget::updateConversationView(const std::string& convUid) { - if (convUid != selectedConvUid()) { + if (convUid != LRCInstance::getSelectedConvUid()) { return; } } @@ -1109,7 +1055,7 @@ CallWidget::selectConversation(const QModelIndex& index) if (selectConversation(item, *currentConversationModel)) { showIMOutOfCall(index); - auto convUid = selectedConvUid(); + auto convUid = LRCInstance::getSelectedConvUid(); if (!lastConvUid_.compare(convUid)) { return; } @@ -1131,7 +1077,7 @@ bool CallWidget::selectConversation( const lrc::api::conversation::Info& item, lrc::api::ConversationModel& convModel) { - if (selectedConvUid() == item.uid) { + if (LRCInstance::getSelectedConvUid() == item.uid) { return false; } else if (item.participants.size() > 0) { convModel.selectConversation(item.uid); @@ -1166,7 +1112,7 @@ CallWidget::updateConversationForNewContact(const std::string& convUid) return; } ui->ringContactLineEdit->setText(""); - auto selectedUid = selectedConvUid(); + auto selectedUid = LRCInstance::getSelectedConvUid(); auto it = Utils::getConversationFromUid(convUid, *convModel); if (it != convModel->allFilteredConversations().end()) { try { @@ -1184,10 +1130,13 @@ CallWidget::updateConversationForNewContact(const std::string& convUid) void CallWidget::updateSmartList() { - auto& currentAccountInfo = LRCInstance::getCurrentAccountInfo(); - smartListModel_.reset(new SmartListModel(currentAccountInfo, this)); - ui->smartList->setModel(smartListModel_.get()); - ui->smartList->setItemDelegate(new ConversationItemDelegate()); + if (!ui->smartList->model()) { + smartListModel_.reset(new SmartListModel(LRCInstance::getCurrAccId(), this)); + ui->smartList->setModel(smartListModel_.get()); + ui->smartList->setItemDelegate(new ConversationItemDelegate()); + } else { + smartListModel_->setAccount(LRCInstance::getCurrAccId()); + } // smartlist selection QObject::disconnect(smartlistSelectionConnection_); @@ -1211,3 +1160,45 @@ CallWidget::update() updateComboBox(); connectConversationModel(); } + +void +CallWidget::connectAccount(const std::string& accId) +{ + auto callModel = LRCInstance::accountModel().getAccountInfo(accId).callModel.get(); + disconnect(callStatusChangedConnection_); + callStatusChangedConnection_ = QObject::connect(callModel, &lrc::api::NewCallModel::callStatusChanged, + [this, accId](const std::string& callId) { + auto callModel = LRCInstance::accountModel().getAccountInfo(accId).callModel.get(); + auto call = callModel->getCall(callId); + switch (call.status) { + case lrc::api::call::Status::INVALID: + case lrc::api::call::Status::INACTIVE: + case lrc::api::call::Status::ENDED: + case lrc::api::call::Status::PEER_BUSY: + case lrc::api::call::Status::TIMEOUT: + case lrc::api::call::Status::TERMINATING: + { + ui->callStackWidget->hide(); + showConversationView(); + break; + } + default: + break; + } + }); + auto& contactModel = LRCInstance::getCurrentAccountInfo().contactModel; + disconnect(contactAddedConnection_); + contactAddedConnection_ = connect(contactModel.get(), &lrc::api::ContactModel::contactAdded, + [this, &contactModel](const std::string & contactId) { + auto convModel = LRCInstance::getCurrentConversationModel(); + auto currentConversation = Utils::getConversationFromUid(LRCInstance::getSelectedConvUid(), + *convModel); + if (currentConversation == convModel->allFilteredConversations().end()) { + return; + } + if (contactId == contactModel.get()->getContact((*currentConversation).participants.at(0)).profileInfo.uri) { + ui->messageView->clear(); + ui->messageView->printHistory(*convModel, currentConversation->interactions); + } + }); +} \ No newline at end of file diff --git a/callwidget.h b/callwidget.h index a7851541fee069d188d000272be6d0b8b8cd1d29..a83387cc898ffe4bdf25f21bb39e7ac7959bae14 100644 --- a/callwidget.h +++ b/callwidget.h @@ -133,8 +133,7 @@ private: void setConversationFilter(lrc::api::profile::Type filter); void updateConversationsFilterWidget(); void updateComboBox(); - const std::string& selectedAccountId(); - const std::string& selectedConvUid(); + void connectAccount(const std::string& accId); QMenu* menu_; @@ -166,5 +165,6 @@ private: QMetaObject::Connection smartlistSelectionConnection_; QMetaObject::Connection interactionRemovedConnection_; QMetaObject::Connection contactAddedConnection_; + QMetaObject::Connection callStatusChangedConnection_; }; diff --git a/callwidget.ui b/callwidget.ui index 73aa9e0323467fe315a9206fb8d4e732971c27ae..f54ba3a432640c8ddb7b9963b1626be302361ee7 100644 --- a/callwidget.ui +++ b/callwidget.ui @@ -381,6 +381,12 @@ <attribute name="headerVisible"> <bool>false</bool> </attribute> + <attribute name="headerDefaultSectionSize"> + <number>0</number> + </attribute> + <attribute name="headerMinimumSectionSize"> + <number>0</number> + </attribute> </widget> </item> </layout> diff --git a/conversationitemdelegate.cpp b/conversationitemdelegate.cpp index 015ee88d94ef22bfdba60b04902401e14ff17cc7..2a31b7da724315c90cc843bd45b859f880433fd5 100644 --- a/conversationitemdelegate.cpp +++ b/conversationitemdelegate.cpp @@ -62,9 +62,15 @@ ConversationItemDelegate::paint(QPainter* painter // menu is open� auto rowHighlight = highlightMap_.find(index.row()); if (selected) { - painter->fillRect(option.rect, RingTheme::smartlistSelection_); + painter->fillRect(option.rect, RingTheme::smartlistSelection_); } else if (rowHighlight != highlightMap_.end() && (*rowHighlight).second) { - painter->fillRect(option.rect, RingTheme::smartlistHighlight_); + painter->fillRect(option.rect, RingTheme::smartlistHighlight_); + } + auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString(); + auto conversation = Utils::getConversationFromUid(convUid, *LRCInstance::getCurrentConversationModel()); + if (LRCInstance::getCurrentCallModel()->hasCall(conversation->callId)) { + auto color = QColor(RingTheme::blue_.lighter(180)); color.setAlpha(128); + painter->fillRect(option.rect, color); } QRect &rect = opt.rect; diff --git a/smartlistmodel.cpp b/smartlistmodel.cpp index be10454b28c79c5bfc1e0b85fefe75962432c05e..18023501a024764465320db554e58ea5773d1213 100644 --- a/smartlistmodel.cpp +++ b/smartlistmodel.cpp @@ -30,17 +30,19 @@ // Client #include "pixbufmanipulator.h" #include "utils.h" +#include "lrcinstance.h" -SmartListModel::SmartListModel(const lrc::api::account::Info &acc, QObject *parent) +SmartListModel::SmartListModel(const std::string& accId, QObject *parent) : QAbstractItemModel(parent), - acc_(acc) + accId_(accId) { } int SmartListModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { - return acc_.conversationModel->allFilteredConversations().size(); + auto& accInfo = LRCInstance::accountModel().getAccountInfo(accId_); + return accInfo.conversationModel->allFilteredConversations().size(); } return 0; // A valid QModelIndex returns 0 as no entry has sub-elements } @@ -57,32 +59,33 @@ QVariant SmartListModel::data(const QModelIndex &index, int role) const return QVariant(); } - const auto& item = acc_.conversationModel->filteredConversation(index.row()); + auto& accInfo = LRCInstance::accountModel().getAccountInfo(accId_); + const auto& item = accInfo.conversationModel->filteredConversation(index.row()); if (item.participants.size() > 0) { try { switch (role) { case Role::Picture: case Qt::DecorationRole: - return GlobalInstances::pixmapManipulator().decorationRole(item, acc_); + return GlobalInstances::pixmapManipulator().decorationRole(item, accInfo); case Role::DisplayName: case Qt::DisplayRole: { - auto& contact = acc_.contactModel->getContact(item.participants[0]); + auto& contact = accInfo.contactModel->getContact(item.participants[0]); return QVariant(QString::fromStdString(Utils::bestNameForContact(contact))); } case Role::DisplayID: { - auto& contact = acc_.contactModel->getContact(item.participants[0]); + auto& contact = accInfo.contactModel->getContact(item.participants[0]); return QVariant(QString::fromStdString(Utils::bestIdForContact(contact))); } case Role::Presence: { - auto& contact = acc_.contactModel->getContact(item.participants[0]); + auto& contact = accInfo.contactModel->getContact(item.participants[0]); return QVariant(contact.isPresent); } case Role::URI: { - auto& contact = acc_.contactModel->getContact(item.participants[0]); + auto& contact = accInfo.contactModel->getContact(item.participants[0]); return QVariant(QString::fromStdString(contact.profileInfo.uri)); } case Role::UnreadMessagesCount: @@ -98,7 +101,7 @@ QVariant SmartListModel::data(const QModelIndex &index, int role) const return QVariant(Utils::toUnderlyingValue(item.interactions.at(item.lastMessageUid).type)); case Role::ContactType: { - auto& contact = acc_.contactModel->getContact(item.participants[0]); + auto& contact = accInfo.contactModel->getContact(item.participants[0]); return QVariant(Utils::toUnderlyingValue(contact.profileInfo.type)); } case Role::UID: @@ -144,3 +147,9 @@ Qt::ItemFlags SmartListModel::flags(const QModelIndex &index) const } return flags; } + +void +SmartListModel::setAccount(const std::string& accId) +{ + accId_ = accId; +} diff --git a/smartlistmodel.h b/smartlistmodel.h index a37cbb126c7e5249e8827eebc703f37875070045..19997db4a7f9892292dc28adf4933db199426d0a 100644 --- a/smartlistmodel.h +++ b/smartlistmodel.h @@ -51,7 +51,7 @@ public: ContextMenuOpen }; - explicit SmartListModel(const lrc::api::account::Info& acc, QObject *parent = 0); + explicit SmartListModel(const std::string& accId, QObject *parent = 0); // QAbstractItemModel int rowCount(const QModelIndex &parent = QModelIndex()) const override; @@ -61,9 +61,11 @@ public: QModelIndex parent(const QModelIndex &child) const; Qt::ItemFlags flags(const QModelIndex &index) const; + void setAccount(const std::string& accId); + // hack for context menu highlight retention bool isContextMenuOpen{ false }; private: - const AccountInfo& acc_; + std::string accId_; }; diff --git a/utils.cpp b/utils.cpp index f5022e94348aa0b651cb5c844389172a1e156928..c3c7d073dfe470fa8d111e28f143c7781ecb0ef8 100644 --- a/utils.cpp +++ b/utils.cpp @@ -42,6 +42,7 @@ #include "pixbufmanipulator.h" #include "globalsystemtray.h" +#include "lrcinstance.h" bool Utils::CreateStartupLink() @@ -428,4 +429,18 @@ Utils::generateTintedPixmap(const QString& filename, QColor color) } } return QPixmap::fromImage(tmpImage); +} + +std::string +Utils::getConversationFromCallId(const std::string& callId) +{ + auto convModel = LRCInstance::getCurrentConversationModel(); + auto conversations = convModel->allFilteredConversations(); + std::string convUid; + for (auto conversation : conversations) { + if (conversation.callId == callId) { + return conversation.uid; + } + } + return ""; } \ No newline at end of file diff --git a/utils.h b/utils.h index 5e6605200705438bd4f1b2fe07476dbdd917cd46..4e081d84a07d8098824fb9db848c705ffac32ec7 100644 --- a/utils.h +++ b/utils.h @@ -78,6 +78,7 @@ namespace Utils QImage conversationPhoto(const std::string& convUid, const lrc::api::account::Info& accountInfo); QByteArray QByteArrayFromFile(const QString& filename); QPixmap generateTintedPixmap(const QString& filename, QColor color); + std::string getConversationFromCallId(const std::string& callId); template<typename E> constexpr inline typename std::enable_if< std::is_enum<E>::value,