From 345c90d244f5655e04608ee9967950d5a29b0f2b Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Thu, 21 Nov 2024 16:36:35 +0100 Subject: [PATCH] Fix display name change propagation: - fullname algo into FriendModel instead of Core. - signal to core wiith friendUpdated (no SDK cb for that, we need to implement it ourself). - Fix call logs details blinking. --- .../core/call-history/CallHistoryCore.cpp | 57 ++++++++++++------- .../core/call-history/CallHistoryCore.hpp | 3 + Linphone/core/friend/FriendCore.cpp | 20 +++---- Linphone/core/friend/FriendCore.hpp | 1 - Linphone/model/core/CoreModel.hpp | 1 + Linphone/model/friend/FriendModel.cpp | 38 +++++++++++++ Linphone/model/friend/FriendModel.hpp | 5 ++ Linphone/view/Page/Main/Call/CallPage.qml | 10 +--- 8 files changed, 94 insertions(+), 41 deletions(-) diff --git a/Linphone/core/call-history/CallHistoryCore.cpp b/Linphone/core/call-history/CallHistoryCore.cpp index f06ad29ab..34a63a3a3 100644 --- a/Linphone/core/call-history/CallHistoryCore.cpp +++ b/Linphone/core/call-history/CallHistoryCore.cpp @@ -62,12 +62,11 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr &callL mDisplayName = Utils::coreStringToAppString(confinfo->getSubject()); } else { mRemoteAddress = Utils::coreStringToAppString(addr->asStringUriOnly()); - mDisplayName = ToolModel::getDisplayName(Utils::coreStringToAppString(addr->asStringUriOnly())); - auto inFriend = Utils::findFriendByAddress(mRemoteAddress); - if (inFriend) { - auto friendGui = inFriend->getValue().value(); - if (friendGui) mDisplayName = friendGui->getCore()->getFullName(); - } + auto linphoneFriend = ToolModel::findFriendByAddress(mRemoteAddress); + if (linphoneFriend) { + mFriendModel = Utils::makeQObject_ptr(linphoneFriend); + mDisplayName = mFriendModel->getFullName(); + } else mDisplayName = ToolModel::getDisplayName(Utils::coreStringToAppString(addr->asStringUriOnly())); } } @@ -81,24 +80,44 @@ void CallHistoryCore::setSelf(QSharedPointer me) { new SafeConnection(me, mCallHistoryModel), &QObject::deleteLater); mCoreModelConnection = QSharedPointer>( new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); + if (mFriendModel) { + mFriendModelConnection = QSharedPointer>( + new SafeConnection(me, mFriendModel), &QObject::deleteLater); + mFriendModelConnection->makeConnectToModel(&FriendModel::fullNameChanged, [this]() { + auto fullName = mFriendModel->getFullName(); + mCoreModelConnection->invokeToCore([this, fullName]() { + if (fullName != mDisplayName) { + mDisplayName = fullName; + emit displayNameChanged(); + } + }); + }); + } if (!ToolModel::findFriendByAddress(mRemoteAddress)) { mCoreModelConnection->makeConnectToModel( &CoreModel::friendCreated, [this, remoteAddress = mRemoteAddress](const std::shared_ptr &f) { - auto inFriend = Utils::findFriendByAddress(remoteAddress); - QString displayName; - if (inFriend) { - auto friendGui = inFriend->getValue().value(); - if (friendGui) displayName = friendGui->getCore()->getFullName(); - } - if (!displayName.isEmpty()) { - mCoreModelConnection->invokeToCore([this, displayName]() { - if (displayName != mDisplayName) { - mDisplayName = displayName; - emit displayNameChanged(); - } + auto friendModel = Utils::makeQObject_ptr(f); + auto displayName = friendModel->getFullName(); + mCoreModelConnection->invokeToCore([this, friendModel, displayName]() { + mFriendModel = friendModel; + auto me = mCoreModelConnection->mCore.mQData; // Locked from previous call. + mFriendModelConnection = QSharedPointer>( + new SafeConnection(me, mFriendModel), &QObject::deleteLater); + mFriendModelConnection->makeConnectToModel(&FriendModel::fullNameChanged, [this]() { + auto fullName = mFriendModel->getFullName(); + mCoreModelConnection->invokeToCore([this, fullName]() { + if (fullName != mDisplayName) { + mDisplayName = fullName; + emit displayNameChanged(); + } + }); }); - } + if (displayName != mDisplayName) { + mDisplayName = displayName; + emit displayNameChanged(); + } + }); }); } } diff --git a/Linphone/core/call-history/CallHistoryCore.hpp b/Linphone/core/call-history/CallHistoryCore.hpp index 9ecd651bd..f13b07b35 100644 --- a/Linphone/core/call-history/CallHistoryCore.hpp +++ b/Linphone/core/call-history/CallHistoryCore.hpp @@ -30,6 +30,7 @@ #include class CallHistoryModel; +class FriendModel; class CallHistoryCore : public QObject, public AbstractObject { Q_OBJECT @@ -72,6 +73,8 @@ private: QString mDuration; QSharedPointer mConferenceInfo = nullptr; std::shared_ptr mCallHistoryModel; + std::shared_ptr mFriendModel; + QSharedPointer> mFriendModelConnection; QSharedPointer> mHistoryModelConnection; QSharedPointer> mCoreModelConnection; diff --git a/Linphone/core/friend/FriendCore.cpp b/Linphone/core/friend/FriendCore.cpp index 03261dc0d..135906206 100644 --- a/Linphone/core/friend/FriendCore.cpp +++ b/Linphone/core/friend/FriendCore.cpp @@ -60,6 +60,7 @@ FriendCore::FriendCore(const std::shared_ptr &contact, bool is mConsolidatedPresence = LinphoneEnums::fromLinphone(contact->getConsolidatedPresence()); mPresenceTimestamp = mFriendModel->getPresenceTimestamp(); mPictureUri = Utils::coreStringToAppString(contact->getPhoto()); + mFullName = mFriendModel->getFullName(); auto defaultAddress = contact->getAddress(); auto vcard = contact->getVcard(); if (vcard) { @@ -67,11 +68,8 @@ FriendCore::FriendCore(const std::shared_ptr &contact, bool is mJob = Utils::coreStringToAppString(vcard->getJobTitle()); mGivenName = Utils::coreStringToAppString(vcard->getGivenName()); mFamilyName = Utils::coreStringToAppString(vcard->getFamilyName()); - mFullName = Utils::coreStringToAppString(vcard->getFullName()); mVCardString = Utils::coreStringToAppString(vcard->asVcard4String()); } - if (mFullName.isEmpty()) mFullName = Utils::coreStringToAppString(contact->getName()); - if (mFullName.isEmpty()) mFullName = Utils::coreStringToAppString(contact->getOrganization()); auto addresses = contact->getAddresses(); for (auto &address : addresses) { @@ -108,12 +106,6 @@ FriendCore::FriendCore(const std::shared_ptr &contact, bool is mIsLdap = ToolModel::friendIsInFriendList(ToolModel::getLdapFriendList(), contact); connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged); connect(this, &FriendCore::phoneNumberChanged, &FriendCore::allAddressesChanged); - auto updateFullName = [this] { - auto name = mGivenName + (!mGivenName.isEmpty() && !mFamilyName.isEmpty() ? " " : "") + mFamilyName; - if (!name.isEmpty()) setFullName(name); - }; - connect(this, &FriendCore::givenNameChanged, updateFullName); - connect(this, &FriendCore::familyNameChanged, updateFullName); } FriendCore::FriendCore(const FriendCore &friendCore) { @@ -181,6 +173,9 @@ void FriendCore::setSelf(QSharedPointer me) { mFriendModelConnection->makeConnectToModel(&FriendModel::organizationChanged, [this](const QString &orga) { mFriendModelConnection->invokeToCore([this, orga]() { setOrganization(orga); }); }); + mFriendModelConnection->makeConnectToModel(&FriendModel::fullNameChanged, [this](const QString &name) { + mFriendModelConnection->invokeToCore([this, name]() { setFullName(name); }); + }); mFriendModelConnection->makeConnectToModel(&FriendModel::jobChanged, [this](const QString &job) { mFriendModelConnection->invokeToCore([this, job]() { setJob(job); }); }); @@ -248,14 +243,14 @@ void FriendCore::reset(const FriendCore &contact) { setGivenName(contact.getGivenName()); setFamilyName(contact.getFamilyName()); setOrganization(contact.getOrganization()); + setFullName(contact.getFullName()); setJob(contact.getJob()); setPictureUri(contact.getPictureUri()); setIsSaved(mFriendModel != nullptr); } QString FriendCore::getFullName() const { - if (mFullName.isEmpty()) return mGivenName + " " + mFamilyName; - else return mFullName; + return mFullName; } void FriendCore::setFullName(const QString &name) { @@ -563,13 +558,14 @@ void FriendCore::writeIntoModel(std::shared_ptr model) const { phones.push_back(num); } model->resetPhoneNumbers(phones); - model->setGivenName(mGivenName); model->setFamilyName(mFamilyName); model->setOrganization(mOrganization); + model->setFullName(mFullName); model->setJob(mJob); model->setPictureUri(mPictureUri); model->getFriend()->done(); + emit CoreModel::getInstance()->friendUpdated(model->getFriend()); } void FriendCore::writeFromModel(const std::shared_ptr &model) { diff --git a/Linphone/core/friend/FriendCore.hpp b/Linphone/core/friend/FriendCore.hpp index b0db873df..b3d1c6c6b 100644 --- a/Linphone/core/friend/FriendCore.hpp +++ b/Linphone/core/friend/FriendCore.hpp @@ -154,7 +154,6 @@ protected: signals: void contactUpdated(); - void displayNameChanged(); void givenNameChanged(QString name); void familyNameChanged(QString name); void fullNameChanged(QString name); diff --git a/Linphone/model/core/CoreModel.hpp b/Linphone/model/core/CoreModel.hpp index 96a0a1dda..4a2fbed3a 100644 --- a/Linphone/model/core/CoreModel.hpp +++ b/Linphone/model/core/CoreModel.hpp @@ -66,6 +66,7 @@ public: signals: void loggerInitialized(); void friendCreated(const std::shared_ptr &f); + void friendUpdated(const std::shared_ptr &f); void friendRemoved(const std::shared_ptr &f); void conferenceInfoCreated(const std::shared_ptr &confInfo); void unreadNotificationsChanged(); diff --git a/Linphone/model/friend/FriendModel.cpp b/Linphone/model/friend/FriendModel.cpp index ba9dcc627..ee8e00e6f 100644 --- a/Linphone/model/friend/FriendModel.cpp +++ b/Linphone/model/friend/FriendModel.cpp @@ -21,6 +21,7 @@ #include "FriendModel.hpp" #include "core/path/Paths.hpp" +#include "model/core/CoreModel.hpp" #include "tool/Utils.hpp" #include "tool/providers/AvatarProvider.hpp" #include @@ -41,6 +42,31 @@ FriendModel::FriendModel(const std::shared_ptr &contact, const }); if (!contact->getName().empty() || !name.isEmpty()) mMonitor->setName(contact->getName().empty() ? Utils::appStringToCoreString(name) : contact->getName()); + auto vcard = contact->getVcard(); + if (vcard) { + mFullName = Utils::coreStringToAppString(vcard->getFullName()); + } + if (mFullName.isEmpty()) mFullName = Utils::coreStringToAppString(contact->getName()); + if (mFullName.isEmpty()) mFullName = Utils::coreStringToAppString(contact->getOrganization()); + auto updateFullName = [this] { + QStringList fullName; + fullName << getGivenName() << getFamilyName(); + fullName.removeAll(""); + setFullName(fullName.join(" ")); + }; + connect(this, &FriendModel::givenNameChanged, updateFullName); + connect(this, &FriendModel::familyNameChanged, updateFullName); + connect(CoreModel::getInstance().get(), &CoreModel::friendUpdated, + [this](const std::shared_ptr &f) { + if (f == mMonitor) { + emit givenNameChanged(getGivenName()); + emit familyNameChanged(getFamilyName()); + emit organizationChanged(getOrganization()); + emit jobChanged(getJob()); + emit pictureUriChanged(getPictureUri()); + // emit starredChanged(getStarred()); // FriendCore do save() on change. Do not call it. + } + }); }; FriendModel::~FriendModel() { @@ -140,6 +166,18 @@ void FriendModel::clearAddresses() { emit addressesChanged(); } +QString FriendModel::getFullName() const { + if (mFullName.isEmpty()) return getGivenName() + " " + getFamilyName(); + else return mFullName; +} + +void FriendModel::setFullName(const QString &name) { + if (mFullName != name) { + mFullName = name; + emit fullNameChanged(name); + } +} + QString FriendModel::getName() const { auto vcard = mMonitor->getVcard(); bool created = false; diff --git a/Linphone/model/friend/FriendModel.hpp b/Linphone/model/friend/FriendModel.hpp index 7fec35892..961516180 100644 --- a/Linphone/model/friend/FriendModel.hpp +++ b/Linphone/model/friend/FriendModel.hpp @@ -45,6 +45,7 @@ public: QDateTime getPresenceTimestamp() const; std::list> getPhoneNumbers() const; std::list> getAddresses() const; + QString getFullName() const; QString getName() const; QString getGivenName() const; QString getFamilyName() const; @@ -72,6 +73,7 @@ protected: void removeAddress(const std::shared_ptr &addr); void clearAddresses(); + void setFullName(const QString &name); void setName(const QString &name); void setGivenName(const QString &name); void setFamilyName(const QString &name); @@ -81,6 +83,8 @@ protected: void setPictureUri(const QString &uri); void setStarred(bool starred); + QString mFullName; + signals: void pictureUriChanged(const QString &uri); void starredChanged(bool starred); @@ -88,6 +92,7 @@ signals: void defaultAddressChanged(); void phoneNumbersChanged(); // void nameChanged(const QString &name); + void fullNameChanged(const QString &name); void givenNameChanged(const QString &name); void familyNameChanged(const QString &name); void organizationChanged(const QString &orga); diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index a8138eac4..ac20cd9f3 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -400,9 +400,6 @@ AbstractMainPage { positionViewAtIndex(currentIndex, ListView.Visible) mainItem.selectedRowHistoryGui = model.getAt(currentIndex) } - onCountChanged: { - mainItem.selectedRowHistoryGui = model.getAt(currentIndex) - } onVisibleChanged: { if (!visible) currentIndex = -1 } @@ -654,12 +651,7 @@ AbstractMainPage { contact: contactObj && contactObj.value || null conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || "" - Connections { - target: mainItem.selectedRowHistoryGui?.core ? mainItem.selectedRowHistoryGui.core : null - onDisplayNameChanged: { - mainItem.onSelectedRowHistoryGuiChanged() // to cover displayName & Avatar. - } - } + buttonContent: PopupButton { id: detailOptions anchors.right: parent.right