From ee8a6ab9708381d99568503b26b2d7833e61ddb8 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Mon, 12 Jun 2023 18:05:13 +0200 Subject: [PATCH] Loading optimizations: - Avoid sending signals on chat room creation. - Remove display name caching from contacts and put it into the sip address model. - On adding new address into sip address model, avoid update all layout and use dataChanged. - Reorder Sip address Model and contacts model and make direct connections for prioritized update signals. --- .../components/chat-room/ChatRoomModel.cpp | 6 +- .../src/components/contact/VcardModel.cpp | 19 +++ .../src/components/contact/VcardModel.hpp | 3 + .../components/contacts/ContactsListModel.cpp | 16 -- .../components/contacts/ContactsListModel.hpp | 5 - .../src/components/core/CoreHandlers.cpp | 1 + .../src/components/core/CoreManager.cpp | 5 +- .../sip-addresses/SipAddressesModel.cpp | 156 +++++++++++++----- .../sip-addresses/SipAddressesModel.hpp | 37 +++-- .../components/timeline/TimelineListModel.cpp | 13 +- linphone-app/src/utils/Utils.cpp | 43 +---- 11 files changed, 186 insertions(+), 118 deletions(-) diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp index a574e46d4..56fb0689c 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp @@ -125,9 +125,9 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr& chatRoo // Get messages. mList.clear(); - - setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); - setMissedCallsCount(0); + + mUnreadMessagesCount = mChatRoom->getUnreadMessagesCount(); + mMissedCallsCount = 0; QElapsedTimer timer; timer.start(); diff --git a/linphone-app/src/components/contact/VcardModel.cpp b/linphone-app/src/components/contact/VcardModel.cpp index b31fa3309..38a8d49cf 100644 --- a/linphone-app/src/components/contact/VcardModel.cpp +++ b/linphone-app/src/components/contact/VcardModel.cpp @@ -282,6 +282,25 @@ QVariantList VcardModel::getSipAddresses () const { return list; } +QList> VcardModel::getLinphoneSipAddresses () const { + QList> list; + if(mVcard->getVcard()){ + shared_ptr core = CoreManager::getInstance()->getCore(); + for (const auto &address : mVcard->getVcard()->getImpp()) { + string value = address->getValue(); + shared_ptr linphoneAddress = core->createAddress(value); + + if (linphoneAddress) + list << linphoneAddress; + else + qWarning() << QStringLiteral("Unable to parse sip address: `%1`") + .arg(QString::fromStdString(value)); + } + + } + return list; +} + bool VcardModel::addSipAddress (const QString &sipAddress) { CHECK_VCARD_IS_WRITABLE(this); diff --git a/linphone-app/src/components/contact/VcardModel.hpp b/linphone-app/src/components/contact/VcardModel.hpp index b4828ee38..f96cdcb5e 100644 --- a/linphone-app/src/components/contact/VcardModel.hpp +++ b/linphone-app/src/components/contact/VcardModel.hpp @@ -25,6 +25,8 @@ #include +#include + // ============================================================================= namespace linphone { @@ -69,6 +71,7 @@ public: // --------------------------------------------------------------------------- QVariantList getSipAddresses () const; + QList> getLinphoneSipAddresses () const; QVariantMap getAddress () const; QVariantList getEmails () const; QVariantList getCompanies () const; diff --git a/linphone-app/src/components/contacts/ContactsListModel.cpp b/linphone-app/src/components/contacts/ContactsListModel.cpp index 155149f4b..3e23f6a07 100644 --- a/linphone-app/src/components/contacts/ContactsListModel.cpp +++ b/linphone-app/src/components/contacts/ContactsListModel.cpp @@ -25,7 +25,6 @@ #include "components/contact/VcardModel.hpp" #include "components/core/CoreManager.hpp" #include "components/friend/FriendListListener.hpp" -#include "utils/Utils.hpp" #include "ContactsListModel.hpp" @@ -72,7 +71,6 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren for(auto address : contact->getVcardModel()->getSipAddresses()){ auto addressStr = address.toString(); mOptimizedSearch.remove(addressStr); - mDisplayNameCache.remove(addressStr); } for(auto l : friendsList) @@ -174,32 +172,18 @@ void ContactsListModel::addContact (QSharedPointer contact) { }); QObject::connect(contact.get(), &ContactModel::sipAddressAdded, this, [this, contact](const QString &sipAddress) { mOptimizedSearch[sipAddress] = contact; - mDisplayNameCache.remove(sipAddress); emit sipAddressAdded(contact, sipAddress); }); QObject::connect(contact.get(), &ContactModel::sipAddressRemoved, this, [this, contact](const QString &sipAddress) { mOptimizedSearch.remove(sipAddress); - mDisplayNameCache.remove(sipAddress); emit sipAddressRemoved(contact, sipAddress); }); add(contact); for(auto address : contact->getVcardModel()->getSipAddresses()){ auto addressStr = address.toString(); mOptimizedSearch[addressStr] = contact; - mDisplayNameCache.remove(addressStr); } } -QString ContactsListModel::findDisplayNameFromCache(const QString& address) const{ - auto cached = mDisplayNameCache.find(address); - if(cached != mDisplayNameCache.end()) - return cached.value(); - else - return ""; -} - -void ContactsListModel::addDisplayNameToCache(const QString& address, const QString& displayName){ - mDisplayNameCache[address] = displayName; -} void ContactsListModel::update(){ beginResetModel(); diff --git a/linphone-app/src/components/contacts/ContactsListModel.hpp b/linphone-app/src/components/contacts/ContactsListModel.hpp index cd24e1b4b..93768a758 100644 --- a/linphone-app/src/components/contacts/ContactsListModel.hpp +++ b/linphone-app/src/components/contacts/ContactsListModel.hpp @@ -48,14 +48,11 @@ public: QSharedPointer findContactModelFromSipAddress (const QString &sipAddress) const; QSharedPointer findContactModelFromUsername (const QString &username) const; - QString findDisplayNameFromCache(const QString& address)const; Q_INVOKABLE ContactModel *getContactModelFromAddress (const QString& address) const; Q_INVOKABLE ContactModel *addContact (VcardModel *vcardModel); Q_INVOKABLE void removeContact (ContactModel *contact); - void addDisplayNameToCache(const QString& address, const QString& displayName); - Q_INVOKABLE void cleanAvatars (); Q_INVOKABLE void update (); @@ -82,8 +79,6 @@ private: QMap> mOptimizedSearch; std::list> mLinphoneFriends; std::shared_ptr mFriendListListener; - - QMap mDisplayNameCache; }; #endif // CONTACTS_LIST_MODEL_H_ diff --git a/linphone-app/src/components/core/CoreHandlers.cpp b/linphone-app/src/components/core/CoreHandlers.cpp index 473a8f0fe..14068247b 100644 --- a/linphone-app/src/components/core/CoreHandlers.cpp +++ b/linphone-app/src/components/core/CoreHandlers.cpp @@ -31,6 +31,7 @@ #include "components/notifier/Notifier.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" +#include "components/sip-addresses/SipAddressesModel.hpp" #include "components/timeline/TimelineListModel.hpp" #include "utils/Utils.hpp" diff --git a/linphone-app/src/components/core/CoreManager.cpp b/linphone-app/src/components/core/CoreManager.cpp index 2dee5ca46..6a57252a9 100644 --- a/linphone-app/src/components/core/CoreManager.cpp +++ b/linphone-app/src/components/core/CoreManager.cpp @@ -94,15 +94,16 @@ CoreManager::~CoreManager(){ void CoreManager::initCoreManager(){ qInfo() << "Init CoreManager"; + mContactsListModel = new ContactsListModel(this); + mSipAddressesModel = new SipAddressesModel(this); // at first in order to prioritzed on handler signals. mAccountSettingsModel = new AccountSettingsModel(this); mSettingsModel = new SettingsModel(this); mEmojisSettingsModel = new EmojisSettingsModel(this); mCallsListModel = new CallsListModel(this); mChatModel = new ChatModel(this); - mContactsListModel = new ContactsListModel(this); + mContactsImporterListModel = new ContactsImporterListModel(this); mLdapListModel = new LdapListModel(this); - mSipAddressesModel = new SipAddressesModel(this); mEventCountNotifier = new EventCountNotifier(this); mTimelineListModel = new TimelineListModel(this); mEventCountNotifier->updateUnreadMessageCount(); diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp index a4adaf346..934dd264f 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp +++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp @@ -52,6 +52,46 @@ static inline QVariantMap buildVariantMap (const SipAddressesModel::SipAddressEn }; } +SipAddressesModel::DisplayNames::DisplayNames(QString address){ + if(!address.isEmpty()){ + auto lAddress = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(address)); + if(lAddress){ + mFromDisplayAddress = Utils::coreStringToAppString(lAddress->getDisplayName()); + mFromUsernameAddress = Utils::coreStringToAppString(lAddress->getUsername()); + } + } +} + +SipAddressesModel::DisplayNames::DisplayNames(const std::shared_ptr& lAddress){ + mFromDisplayAddress = Utils::coreStringToAppString(lAddress->getDisplayName()); + mFromUsernameAddress = Utils::coreStringToAppString(lAddress->getUsername()); +} + +QString SipAddressesModel::DisplayNames::get(){ + if(!mFromContact.isEmpty()) + return mFromContact; + else if(!mFromDisplayAddress.isEmpty()) + return mFromDisplayAddress; + else if(!mFromAccount.isEmpty()) + return mFromAccount; + else if(!mFromCallLogs.isEmpty()) + return mFromCallLogs; + else if(!mFromUsernameAddress.isEmpty()) + return mFromUsernameAddress; + else + return ""; +} + +void SipAddressesModel::DisplayNames::updateFromCall(const std::shared_ptr& address){ + auto displayName = address->getDisplayName(); + if(!displayName.empty()) + mFromCallLogs = Utils::coreStringToAppString(displayName); +} + +void SipAddressesModel::DisplayNames::updateFromChatMessage(const std::shared_ptr& address){ + // Not used +} + SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(parent) { initSipAddresses(); @@ -61,17 +101,18 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare QObject::connect(coreManager, &CoreManager::chatRoomModelCreated, this, &SipAddressesModel::handleChatRoomModelCreated); QObject::connect(coreManager, &CoreManager::historyModelCreated, this, &SipAddressesModel::handleHistoryModelCreated); - +//Use blocking in order to apply updates before any use ContactsListModel *contacts = CoreManager::getInstance()->getContactsListModel(); - QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded); - QObject::connect(contacts, &ContactsListModel::contactRemoved, this, &SipAddressesModel::handleContactRemoved); - QObject::connect(contacts, &ContactsListModel::sipAddressAdded, this, &SipAddressesModel::handleSipAddressAdded); - QObject::connect(contacts, &ContactsListModel::sipAddressRemoved, this, &SipAddressesModel::handleSipAddressRemoved); + QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded, Qt::DirectConnection); + QObject::connect(contacts, &ContactsListModel::contactRemoved, this, &SipAddressesModel::handleContactRemoved, Qt::DirectConnection); + QObject::connect(contacts, &ContactsListModel::contactUpdated, this, &SipAddressesModel::handleContactUpdated, Qt::DirectConnection); + QObject::connect(contacts, &ContactsListModel::sipAddressAdded, this, &SipAddressesModel::handleSipAddressAdded, Qt::DirectConnection); + QObject::connect(contacts, &ContactsListModel::sipAddressRemoved, this, &SipAddressesModel::handleSipAddressRemoved, Qt::DirectConnection); CoreHandlers *coreHandlers = mCoreHandlers.get(); - QObject::connect(coreHandlers, &CoreHandlers::messagesReceived, this, &SipAddressesModel::handleMessagesReceived); - QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &SipAddressesModel::handleCallStateChanged); - QObject::connect(coreHandlers, &CoreHandlers::presenceReceived, this, &SipAddressesModel::handlePresenceReceived); + QObject::connect(coreHandlers, &CoreHandlers::messagesReceived, this, &SipAddressesModel::handleMessagesReceived, Qt::DirectConnection); + QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &SipAddressesModel::handleCallStateChanged, Qt::DirectConnection); + QObject::connect(coreHandlers, &CoreHandlers::presenceReceived, this, &SipAddressesModel::handlePresenceReceived, Qt::DirectConnection); QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &SipAddressesModel::handleIsComposingChanged); } @@ -189,6 +230,14 @@ QString SipAddressesModel::addTransportToSipAddress (const QString &sipAddress, return Utils::coreStringToAppString(address->asString()); } +QString SipAddressesModel::getDisplayName(const std::shared_ptr& address){ + std::shared_ptr cleanAddress = address->clone(); + cleanAddress->clean(); + QString qtAddress = Utils::coreStringToAppString(cleanAddress->asStringUriOnly()); + auto sipAddressEntry = getSipAddressEntry(qtAddress, cleanAddress); + return sipAddressEntry->displayNames.get(); +} + // ----------------------------------------------------------------------------- QString SipAddressesModel::interpretSipAddress (const QString &sipAddress, bool checkUsername) { @@ -292,8 +341,8 @@ void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) { } void SipAddressesModel::handleContactAdded (QSharedPointer contact) { - for (const auto &sipAddress : contact->getVcardModel()->getSipAddresses()) { - addOrUpdateSipAddress(sipAddress.toString(), contact); + for (const auto &sipAddress : contact->getVcardModel()->getLinphoneSipAddresses()) { + addOrUpdateSipAddress(Utils::coreStringToAppString(sipAddress->asStringUriOnly()), sipAddress, contact); } } @@ -302,13 +351,26 @@ void SipAddressesModel::handleContactRemoved (QSharedPointer conta removeContactOfSipAddress(sipAddress.toString()); } +void SipAddressesModel::handleContactUpdated (QSharedPointer contact) { + if(contact){ + for(auto entry : mPeerAddressToSipAddressEntry){ + if(entry.contact == contact) + entry.contact = nullptr; + } + for (const auto &sipAddress : contact->getVcardModel()->getLinphoneSipAddresses()) { + addOrUpdateSipAddress(Utils::coreStringToAppString(sipAddress->asStringUriOnly()), sipAddress, contact); + } + } +} + void SipAddressesModel::handleSipAddressAdded (QSharedPointer contact, const QString &sipAddress) { ContactModel *mappedContact = mapSipAddressToContact(sipAddress); if (mappedContact) { qWarning() << "Unable to map sip address" << sipAddress << "to" << contact.get() << "- already used by" << mappedContact; return; } - addOrUpdateSipAddress(sipAddress, contact); + QString cleanedAddress = Utils::cleanSipAddress(sipAddress); + addOrUpdateSipAddress(cleanedAddress, linphone::Factory::get()->createAddress(sipAddress.toStdString()), contact); } void SipAddressesModel::handleSipAddressRemoved (QSharedPointer contact, const QString &sipAddress) { @@ -317,19 +379,21 @@ void SipAddressesModel::handleSipAddressRemoved (QSharedPointer co qWarning() << "Unable to remove sip address" << sipAddress << "of" << contact.get() << "- already used by" << mappedContact; return; } - - removeContactOfSipAddress(sipAddress); + QString cleanedAddress = Utils::cleanSipAddress(sipAddress); + removeContactOfSipAddress(cleanedAddress); } void SipAddressesModel::handleMessageReceived (const shared_ptr &message) { - const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); - addOrUpdateSipAddress(peerAddress, message); + auto lPeerAddress = message->getChatRoom()->getPeerAddress(); + const QString peerAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly())); + addOrUpdateSipAddress(peerAddress, lPeerAddress, message); } void SipAddressesModel::handleMessagesReceived (const std::list> &messages) { for(auto message: messages){ - const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); - addOrUpdateSipAddress(peerAddress, message); + auto lPeerAddress = message->getChatRoom()->getPeerAddress(); + const QString peerAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly())); + addOrUpdateSipAddress(peerAddress, lPeerAddress, message); } } @@ -337,10 +401,8 @@ void SipAddressesModel::handleCallStateChanged ( const shared_ptr &call, linphone::Call::State state ) { - if (state == linphone::Call::State::End || state == linphone::Call::State::Error) - addOrUpdateSipAddress( - Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()), call - ); + auto lPeerAddress = call->getRemoteAddress(); + addOrUpdateSipAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly()), lPeerAddress, call); } void SipAddressesModel::handlePresenceReceived ( @@ -457,8 +519,9 @@ void SipAddressesModel::handleMessageCountReset (ChatRoomModel *chatRoomModel) { void SipAddressesModel::handleMessageSent (const shared_ptr &message) { if(message->getChatRoom() && message->getChatRoom()->getPeerAddress()){ - const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); - addOrUpdateSipAddress(peerAddress, message); + auto lPeerAddress = message->getChatRoom()->getPeerAddress(); + const QString peerAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly())); + addOrUpdateSipAddress(peerAddress, lPeerAddress, message); } } @@ -485,17 +548,22 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const QString &sipAddress = sipAddressEntry.sipAddress; sipAddressEntry.contact = contact; - if (!sipAddressEntry.contact) - qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sipAddress); + if (!sipAddressEntry.contact) { + qDebug() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sipAddress); + sipAddressEntry.displayNames.mFromContact = ""; + }else if(contact->getVcardModel()) + sipAddressEntry.displayNames.mFromContact = contact->getVcardModel()->getUsername(); + else + sipAddressEntry.displayNames.mFromContact = ""; updateObservers(sipAddress, contact); } void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr &call) { const shared_ptr callLog = call->getCallLog(); - + auto lPeerAddress = callLog->getRemoteAddress(); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly()))); - QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()))); + QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly()))); ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[ localAddress ]; @@ -506,6 +574,10 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress); + QString oldDisplayName = sipAddressEntry.displayNames.get(); + sipAddressEntry.displayNames.updateFromCall(lPeerAddress); + if(oldDisplayName != sipAddressEntry.displayNames.get()) + emit CoreManager::getInstance()->getContactsListModel()->contactUpdated(nullptr); updateObservers(sipAddressEntry.sipAddress, localAddress, conferenceEntry.unreadMessageCount,conferenceEntry.missedCallCount); } @@ -516,20 +588,21 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, if (chatRoom->getCurrentParams()->getEncryptionBackend() == linphone::ChatRoom::EncryptionBackend::None && !settingsModel->getStandardChatEnabled() || chatRoom->getCurrentParams()->getEncryptionBackend() != linphone::ChatRoom::EncryptionBackend::None && !settingsModel->getSecureChatEnabled()) count = chatRoom->getUnreadMessagesCount(); - + auto lPeerAddress = chatRoom->getPeerAddress(); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()))); - QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()))); + QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly()))); qInfo() << QStringLiteral("Update (`%1`, `%2`) from chat message.").arg(sipAddressEntry.sipAddress, localAddress); ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[localAddress]; conferenceEntry.timestamp = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000); conferenceEntry.unreadMessageCount = count ; conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress); + sipAddressEntry.displayNames.updateFromChatMessage(lPeerAddress); updateObservers(sipAddressEntry.sipAddress, localAddress, count,conferenceEntry.missedCallCount); } template -void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data) { +void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, const std::shared_ptr peerAddress, T data) { auto it = mPeerAddressToSipAddressEntry.find(sipAddress); if (it != mPeerAddressToSipAddressEntry.end()) { addOrUpdateSipAddress(*it, data); @@ -541,18 +614,17 @@ void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data return; } - SipAddressEntry sipAddressEntry{ sipAddress, nullptr, Presence::Offline, {} }; + SipAddressEntry sipAddressEntry{ sipAddress, nullptr, Presence::Offline, {}, {}, DisplayNames(peerAddress) }; addOrUpdateSipAddress(sipAddressEntry, data); int row = mRefs.count(); - emit layoutAboutToBeChanged(); beginInsertRows(QModelIndex(), row, row); mPeerAddressToSipAddressEntry[sipAddress] = move(sipAddressEntry); mRefs << &mPeerAddressToSipAddressEntry[sipAddress]; endInsertRows(); - emit layoutChanged(); + emit dataChanged(QModelIndex(), index(row,0)); } // ----------------------------------------------------------------------------- @@ -607,10 +679,11 @@ void SipAddressesModel::initSipAddressesFromChat () { auto lastMessage = chatRoom->getLastMessageInHistory(); if( !lastMessage) continue; - QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()))); + auto lPeerAddress = chatRoom->getPeerAddress(); + QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly()))); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()))); - getSipAddressEntry(peerAddress)->localAddressToConferenceEntry[localAddress] = { + getSipAddressEntry(peerAddress, lPeerAddress)->localAddressToConferenceEntry[localAddress] = { chatRoom->getUnreadMessagesCount(), CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress), false, @@ -623,7 +696,8 @@ void SipAddressesModel::initSipAddressesFromCalls () { using ConferenceId = QPair; QSet conferenceDone; for (const auto &callLog : CoreManager::getInstance()->getCore()->getCallLogs()) { - const QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()))); + auto lPeerAddress = callLog->getRemoteAddress(); + const QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(lPeerAddress->asStringUriOnly()))); const QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly()))); @@ -637,12 +711,16 @@ void SipAddressesModel::initSipAddressesFromCalls () { ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000)); - auto &localToConferenceEntry = getSipAddressEntry(peerAddress)->localAddressToConferenceEntry; + auto sipAddressEntry = getSipAddressEntry(peerAddress, lPeerAddress); + auto &localToConferenceEntry = sipAddressEntry->localAddressToConferenceEntry; auto it = localToConferenceEntry.find(localAddress); - if (it == localToConferenceEntry.end()) + if (it == localToConferenceEntry.end()) { localToConferenceEntry[localAddress] = { 0,0, false, move(timestamp) }; - else if (it->timestamp.isNull() || timestamp > it->timestamp) + sipAddressEntry->displayNames.mFromCallLogs = QString::fromStdString(callLog->getRemoteAddress()->getDisplayName()); + }else if (it->timestamp.isNull() || timestamp > it->timestamp){ it->timestamp = move(timestamp); + sipAddressEntry->displayNames.mFromCallLogs = QString::fromStdString(callLog->getRemoteAddress()->getDisplayName()); + } } } diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp index 27f9fb4db..38bcc2ff0 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp +++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp @@ -26,6 +26,7 @@ #include #include "SipAddressObserver.hpp" +#include "utils/Utils.hpp" // ============================================================================= @@ -46,16 +47,33 @@ public: QDateTime timestamp; }; + class DisplayNames{ + public: + DisplayNames(QString address = ""); + DisplayNames(const std::shared_ptr& lAddress); + QString mFromContact; + QString mFromAccount; + QString mFromCallLogs; + QString mFromDisplayAddress; + QString mFromUsernameAddress; + QString get(); + void updateFromCall(const std::shared_ptr& address); + void updateFromChatMessage(const std::shared_ptr& address);// not implemented + }; + struct SipAddressEntry { QString sipAddress; QSharedPointer contact; Presence::PresenceStatus presenceStatus; QDateTime presenceTimestamp; QHash localAddressToConferenceEntry; + DisplayNames displayNames; }; SipAddressesModel (QObject *parent = Q_NULLPTR); + void initSipAddresses (); + void reset(); int rowCount (const QModelIndex &index = QModelIndex()) const override; @@ -75,6 +93,7 @@ public: Q_INVOKABLE static QString getTransportFromSipAddress (const QString &sipAddress); Q_INVOKABLE static QString addTransportToSipAddress (const QString &sipAddress, const QString &transport); + QString getDisplayName(const std::shared_ptr& address); Q_INVOKABLE static QString interpretSipAddress (const QString &sipAddress, bool checkUsername = true); Q_INVOKABLE static QString interpretSipAddress (const QUrl &sipAddress); @@ -86,6 +105,11 @@ public: Q_INVOKABLE static QString cleanSipAddress (const QString &sipAddress); // --------------------------------------------------------------------------- + //NMN TODO bind to missedCall event and implement void addOrUpdateSipAddress + + template + void addOrUpdateSipAddress (const QString &sipAddress, const std::shared_ptr peerAddress, T data); + signals: void sipAddressReset();// The model has been reset @@ -103,6 +127,7 @@ private: void handleContactAdded (QSharedPointer contact); void handleContactRemoved (QSharedPointer contact); + void handleContactUpdated (QSharedPointer contact); void handleSipAddressAdded (QSharedPointer contact, const QString &sipAddress); void handleSipAddressRemoved (QSharedPointer contact, const QString &sipAddress); @@ -129,18 +154,10 @@ private: void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &call); void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &message); - - //NMN TODO bind to missedCall event and implement void addOrUpdateSipAddress - - template - void addOrUpdateSipAddress (const QString &sipAddress, T data); - // --------------------------------------------------------------------------- void removeContactOfSipAddress (const QString &sipAddress); - void initSipAddresses (); - void initSipAddressesFromChat (); void initSipAddressesFromCalls (); void initSipAddressesFromContacts (); @@ -153,10 +170,10 @@ private: // --------------------------------------------------------------------------- - SipAddressEntry *getSipAddressEntry (const QString &peerAddress) { + SipAddressEntry *getSipAddressEntry (const QString &peerAddress, const std::shared_ptr& lAddress) { auto it = mPeerAddressToSipAddressEntry.find(peerAddress); if (it == mPeerAddressToSipAddressEntry.end()) - it = mPeerAddressToSipAddressEntry.insert(peerAddress, { peerAddress, nullptr, Presence::Offline, {} }); + it = mPeerAddressToSipAddressEntry.insert(peerAddress, { peerAddress, nullptr, Presence::Offline, {}, {}, DisplayNames(lAddress) }); return &(*it); } QHash mPeerAddressToSipAddressEntry; diff --git a/linphone-app/src/components/timeline/TimelineListModel.cpp b/linphone-app/src/components/timeline/TimelineListModel.cpp index 96ec24ea7..375d46269 100644 --- a/linphone-app/src/components/timeline/TimelineListModel.cpp +++ b/linphone-app/src/components/timeline/TimelineListModel.cpp @@ -34,6 +34,7 @@ #include "TimelineListModel.hpp" #include +#include // ============================================================================= @@ -240,6 +241,10 @@ void TimelineListModel::onSelectedHasChanged(bool selected){ } void TimelineListModel::updateTimelines () { + QElapsedTimer timer, stepsTimer; + timer.start(); + + stepsTimer.start(); CoreManager *coreManager = CoreManager::getInstance(); std::list> allChatRooms = coreManager->getCore()->getChatRooms(); @@ -259,7 +264,7 @@ void TimelineListModel::updateTimelines () { } return false; }); - + qInfo() << "Timelines cleaning :" << stepsTimer.restart() << "ms."; //Remove no more chat rooms auto itTimeline = mList.begin(); while(itTimeline != mList.end()) { @@ -291,6 +296,7 @@ void TimelineListModel::updateTimelines () { }else ++itTimeline; } + qInfo() << "Timelines removing expired :" << stepsTimer.restart() << "ms."; // Add new. // Call logs optimization : store all the list and check on it for each chat room instead of loading call logs on each chat room. See TimelineModel() std::list> callLogs = coreManager->getCore()->getCallLogs(); @@ -308,7 +314,7 @@ void TimelineListModel::updateTimelines () { optimizedCallLogs[localAddress][peerAddress] = callLog; } } - + qInfo() << "Timelines optimization for build :" << stepsTimer.restart() << "ms."; for(auto dbChatRoom : allChatRooms){ auto haveTimeline = getTimeline(dbChatRoom, false); if(!haveTimeline && dbChatRoom){// Create a new Timeline if needed @@ -319,8 +325,11 @@ void TimelineListModel::updateTimelines () { } } } + qInfo() << "Timelines adding :" << stepsTimer.restart() << "ms."; add(models); + qInfo() << "Timelines adding GUI :" << stepsTimer.restart() << "ms."; CoreManager::getInstance()->updateUnreadMessageCount(); + qInfo() << "Timelines initialized in:" << timer.elapsed() << "ms."; } void TimelineListModel::add (QSharedPointer timeline){ diff --git a/linphone-app/src/utils/Utils.cpp b/linphone-app/src/utils/Utils.cpp index a0d3cee16..edf60e9a1 100644 --- a/linphone-app/src/utils/Utils.cpp +++ b/linphone-app/src/utils/Utils.cpp @@ -52,6 +52,7 @@ #include "components/contact/VcardModel.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" +#include "components/sip-addresses/SipAddressesModel.hpp" #ifdef _WIN32 @@ -542,47 +543,7 @@ void Utils::copyDir(QString from, QString to) { QString Utils::getDisplayName(const std::shared_ptr& address){ QString displayName; if(address){ - std::shared_ptr cleanAddress = address->clone(); - cleanAddress->clean(); - QString qtAddress = Utils::coreStringToAppString(cleanAddress->asStringUriOnly()); - displayName = CoreManager::getInstance()->getContactsListModel()->findDisplayNameFromCache(qtAddress); - - if(displayName.isEmpty()){ - auto model = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(qtAddress); - if(model && model->getVcardModel()) - displayName = model->getVcardModel()->getUsername(); - else{ - // Try to get display from full address - displayName = QString::fromStdString(address->getDisplayName()); - if( displayName == ""){ - // Try to get display name from proxies - auto accounts = CoreManager::getInstance()->getCore()->getAccountList(); - for(auto accountIt = accounts.begin() ; displayName=="" && accountIt != accounts.end() ; ++accountIt){ - auto params = accountIt->get()->getParams(); - if(params){ - auto accountAddress = params->getIdentityAddress(); - if(accountAddress && accountAddress->weakEqual(address)){ - displayName = Utils::coreStringToAppString(accountAddress->getDisplayName()); - } - } - } - if(displayName == ""){ - // Try to get display name from logs - auto callHistory = CoreManager::getInstance()->getCore()->getCallLogs(); - auto callLog = std::find_if(callHistory.begin(), callHistory.end(), [address](std::shared_ptr& cl){ - return cl->getRemoteAddress()->weakEqual(address); - }); - if(callLog != callHistory.end()) - displayName = QString::fromStdString((*callLog)->getRemoteAddress()->getDisplayName()); - if(displayName == "") - displayName = QString::fromStdString(address->getDisplayName()); - if(displayName == "") - displayName = Utils::coreStringToAppString(address->getUsername()); - } - } - CoreManager::getInstance()->getContactsListModel()->addDisplayNameToCache(qtAddress, displayName); - } - } + displayName = CoreManager::getInstance()->getSipAddressesModel()->getDisplayName(address); } return displayName; }