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.
This commit is contained in:
Julien Wadel 2023-06-12 18:05:13 +02:00
parent ff4f4af22a
commit ee8a6ab970
11 changed files with 186 additions and 118 deletions

View file

@ -125,9 +125,9 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoo
// Get messages.
mList.clear();
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
setMissedCallsCount(0);
mUnreadMessagesCount = mChatRoom->getUnreadMessagesCount();
mMissedCallsCount = 0;
QElapsedTimer timer;
timer.start();

View file

@ -282,6 +282,25 @@ QVariantList VcardModel::getSipAddresses () const {
return list;
}
QList<std::shared_ptr<linphone::Address>> VcardModel::getLinphoneSipAddresses () const {
QList<std::shared_ptr<linphone::Address>> list;
if(mVcard->getVcard()){
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
for (const auto &address : mVcard->getVcard()->getImpp()) {
string value = address->getValue();
shared_ptr<linphone::Address> 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);

View file

@ -25,6 +25,8 @@
#include <QObject>
#include <linphone++/linphone.hh>
// =============================================================================
namespace linphone {
@ -69,6 +71,7 @@ public:
// ---------------------------------------------------------------------------
QVariantList getSipAddresses () const;
QList<std::shared_ptr<linphone::Address>> getLinphoneSipAddresses () const;
QVariantMap getAddress () const;
QVariantList getEmails () const;
QVariantList getCompanies () const;

View file

@ -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<ContactModel> 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<ContactModel>(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();

View file

@ -48,14 +48,11 @@ public:
QSharedPointer<ContactModel> findContactModelFromSipAddress (const QString &sipAddress) const;
QSharedPointer<ContactModel> 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<QString, QSharedPointer<ContactModel>> mOptimizedSearch;
std::list<std::shared_ptr<linphone::FriendList>> mLinphoneFriends;
std::shared_ptr<FriendListListener> mFriendListListener;
QMap<QString, QString> mDisplayNameCache;
};
#endif // CONTACTS_LIST_MODEL_H_

View file

@ -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"

View file

@ -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();

View file

@ -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<const linphone::Address>& 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<const linphone::Address>& address){
auto displayName = address->getDisplayName();
if(!displayName.empty())
mFromCallLogs = Utils::coreStringToAppString(displayName);
}
void SipAddressesModel::DisplayNames::updateFromChatMessage(const std::shared_ptr<const linphone::Address>& 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<const linphone::Address>& address){
std::shared_ptr<linphone::Address> 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<ContactModel> 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<ContactModel> conta
removeContactOfSipAddress(sipAddress.toString());
}
void SipAddressesModel::handleContactUpdated (QSharedPointer<ContactModel> 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<ContactModel> 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<ContactModel> contact, const QString &sipAddress) {
@ -317,19 +379,21 @@ void SipAddressesModel::handleSipAddressRemoved (QSharedPointer<ContactModel> 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<linphone::ChatMessage> &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<shared_ptr<linphone::ChatMessage>> &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<linphone::Call> &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<linphone::ChatMessage> &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<linphone::Call> &call) {
const shared_ptr<linphone::CallLog> 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<typename T>
void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data) {
void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, const std::shared_ptr<const linphone::Address> 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<QString, QString>;
QSet<ConferenceId> 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());
}
}
}

View file

@ -26,6 +26,7 @@
#include <QSharedPointer>
#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<const linphone::Address>& lAddress);
QString mFromContact;
QString mFromAccount;
QString mFromCallLogs;
QString mFromDisplayAddress;
QString mFromUsernameAddress;
QString get();
void updateFromCall(const std::shared_ptr<const linphone::Address>& address);
void updateFromChatMessage(const std::shared_ptr<const linphone::Address>& address);// not implemented
};
struct SipAddressEntry {
QString sipAddress;
QSharedPointer<ContactModel> contact;
Presence::PresenceStatus presenceStatus;
QDateTime presenceTimestamp;
QHash<QString, ConferenceEntry> 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<const linphone::Address>& 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<class T>
void addOrUpdateSipAddress (const QString &sipAddress, const std::shared_ptr<const linphone::Address> peerAddress, T data);
signals:
void sipAddressReset();// The model has been reset
@ -103,6 +127,7 @@ private:
void handleContactAdded (QSharedPointer<ContactModel> contact);
void handleContactRemoved (QSharedPointer<ContactModel> contact);
void handleContactUpdated (QSharedPointer<ContactModel> contact);
void handleSipAddressAdded (QSharedPointer<ContactModel> contact, const QString &sipAddress);
void handleSipAddressRemoved (QSharedPointer<ContactModel> contact, const QString &sipAddress);
@ -129,18 +154,10 @@ private:
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr<linphone::Call> &call);
void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr<linphone::ChatMessage> &message);
//NMN TODO bind to missedCall event and implement void addOrUpdateSipAddress
template<class T>
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<const linphone::Address>& 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<QString, SipAddressEntry> mPeerAddressToSipAddressEntry;

View file

@ -34,6 +34,7 @@
#include "TimelineListModel.hpp"
#include <QDebug>
#include <QElapsedTimer>
// =============================================================================
@ -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<std::shared_ptr<linphone::ChatRoom>> 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<std::shared_ptr<linphone::CallLog>> 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<TimelineModel> timeline){

View file

@ -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<const linphone::Address>& address){
QString displayName;
if(address){
std::shared_ptr<linphone::Address> 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<linphone::CallLog>& 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;
}