diff --git a/Linphone/core/call-history/CallHistoryCore.cpp b/Linphone/core/call-history/CallHistoryCore.cpp index 8d715e812..c6ff22317 100644 --- a/Linphone/core/call-history/CallHistoryCore.cpp +++ b/Linphone/core/call-history/CallHistoryCore.cpp @@ -93,42 +93,44 @@ void CallHistoryCore::setSelf(QSharedPointer me) { }); }); } - if (!ToolModel::findFriendByAddress(mRemoteAddress)) { - mCoreModelConnection->makeConnectToModel( - &CoreModel::friendCreated, - [this, remoteAddress = mRemoteAddress](const std::shared_ptr &f) { - auto friendModel = Utils::makeQObject_ptr(f); - auto displayName = friendModel->getFullName(); - auto fAddress = ToolModel::interpretUrl(remoteAddress); - bool isThisFriend = false; - for (auto f : friendModel->getAddresses()) { - if (f->weakEqual(fAddress)) { - isThisFriend = true; - break; - } - } - if (isThisFriend) - 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(); - } - emit friendAdded(); - }); - }); + auto update = [this, remoteAddress = mRemoteAddress](const std::shared_ptr &updatedFriend) { + auto friendModel = Utils::makeQObject_ptr(updatedFriend); + auto displayName = friendModel->getFullName(); + auto fAddress = ToolModel::interpretUrl(remoteAddress); + bool isThisFriend = false; + for (auto f : friendModel->getAddresses()) { + if (f->weakEqual(fAddress)) { + isThisFriend = true; + break; + } + } + if (isThisFriend) + 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(); + } + emit friendUpdated(); + }); + }; + if (!ToolModel::findFriendByAddress(mRemoteAddress)) + mCoreModelConnection->makeConnectToModel(&CoreModel::friendCreated, update); + else { + mCoreModelConnection->makeConnectToModel(&CoreModel::friendUpdated, update); + mCoreModelConnection->makeConnectToModel(&CoreModel::friendRemoved, &CallHistoryCore::onRemoved); } } @@ -154,3 +156,23 @@ void CallHistoryCore::remove() { emit removed(); }); } + +void CallHistoryCore::onRemoved(const std::shared_ptr &updatedFriend) { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + auto fAddress = ToolModel::interpretUrl(mRemoteAddress); + bool isThisFriend = mFriendModel && updatedFriend == mFriendModel->getFriend(); + if (!isThisFriend) + for (auto f : updatedFriend->getAddresses()) { + if (f->weakEqual(fAddress)) { + isThisFriend = true; + break; + } + } + if (isThisFriend) { + mFriendModel = nullptr; + mFriendModelConnection = nullptr; + mDisplayName = ToolModel::getDisplayName(mRemoteAddress); + emit displayNameChanged(); + emit friendUpdated(); + } +}; diff --git a/Linphone/core/call-history/CallHistoryCore.hpp b/Linphone/core/call-history/CallHistoryCore.hpp index d3e78deef..b39364085 100644 --- a/Linphone/core/call-history/CallHistoryCore.hpp +++ b/Linphone/core/call-history/CallHistoryCore.hpp @@ -55,6 +55,8 @@ public: QString getDuration() const; void setDuration(const QString &duration); + void onRemoved(const std::shared_ptr &updatedFriend); + Q_INVOKABLE void remove(); QString mRemoteAddress; @@ -68,7 +70,7 @@ public: signals: void durationChanged(QString duration); void displayNameChanged(); - void friendAdded(); // When a friend is created, this log is linked to it. + void friendUpdated(); // When a friend is created, this log is linked to it. void removed(); private: diff --git a/Linphone/core/friend/FriendCore.cpp b/Linphone/core/friend/FriendCore.cpp index 8e7d1ac05..351243a3c 100644 --- a/Linphone/core/friend/FriendCore.cpp +++ b/Linphone/core/friend/FriendCore.cpp @@ -125,6 +125,11 @@ void FriendCore::setSelf(QSharedPointer me) { if (mFriendModel) { mFriendModelConnection = QSharedPointer>( new SafeConnection(me, mFriendModel), &QObject::deleteLater); + mFriendModelConnection->makeConnectToModel(&FriendModel::updated, [this]() { + mFriendModelConnection->invokeToCore([this]() { emit friendUpdated(); }); + }); + mFriendModelConnection->makeConnectToModel( + &FriendModel::removed, [this]() { mFriendModelConnection->invokeToCore([this]() { removed(this); }); }); mFriendModelConnection->makeConnectToModel( &FriendModel::presenceReceived, [this](LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp) { @@ -566,7 +571,7 @@ void FriendCore::writeIntoModel(std::shared_ptr model) const { model->setJob(mJob); model->setPictureUri(mPictureUri); model->getFriend()->done(); - emit model->friendUpdated(); + emit model->updated(); } void FriendCore::writeFromModel(const std::shared_ptr &model) { @@ -594,12 +599,7 @@ void FriendCore::writeFromModel(const std::shared_ptr &model) { void FriendCore::remove() { if (mFriendModel) { // Update - mFriendModelConnection->invokeToModel([this]() { - auto contact = mFriendModel->getFriend(); - // emit CoreModel::getInstance()->friendRemoved(contact); - contact->remove(); - mFriendModelConnection->invokeToCore([this]() { removed(this); }); - }); + mFriendModelConnection->invokeToModel([this]() { mFriendModel->remove(); }); } } @@ -705,3 +705,7 @@ bool FriendCore::getReadOnly() const { return isLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list= & // CardDAV } + +std::shared_ptr FriendCore::getFriendModel() { + return mFriendModel; +} diff --git a/Linphone/core/friend/FriendCore.hpp b/Linphone/core/friend/FriendCore.hpp index b4e29ffa5..f6a31158d 100644 --- a/Linphone/core/friend/FriendCore.hpp +++ b/Linphone/core/friend/FriendCore.hpp @@ -148,6 +148,8 @@ public: bool isLdap() const; bool getReadOnly() const; + std::shared_ptr getFriendModel(); + Q_INVOKABLE void remove(); Q_INVOKABLE void save(); Q_INVOKABLE void undo(); @@ -157,7 +159,7 @@ protected: void resetAddresses(QList newList); signals: - void contactUpdated(); + void friendUpdated(); void givenNameChanged(QString name); void familyNameChanged(QString name); void fullNameChanged(QString name); diff --git a/Linphone/core/proxy/ListProxy.hpp b/Linphone/core/proxy/ListProxy.hpp index 5ef11eb20..0a3ac29d9 100644 --- a/Linphone/core/proxy/ListProxy.hpp +++ b/Linphone/core/proxy/ListProxy.hpp @@ -114,8 +114,9 @@ public: break; } else ++index; if (!removed) - qWarning() << QStringLiteral("Unable to remove ") << itemToRemove->metaObject()->className() - << QStringLiteral(" : ") << itemToRemove; + qWarning() << QStringLiteral("Item not found. Unable to remove ") + << itemToRemove->metaObject()->className() << QStringLiteral(" : ") << itemToRemove + << ", Count=" << mList.count() << ", index=" << index; } return removed; } diff --git a/Linphone/core/search/MagicSearchList.cpp b/Linphone/core/search/MagicSearchList.cpp index f7207157d..c22e3d1da 100644 --- a/Linphone/core/search/MagicSearchList.cpp +++ b/Linphone/core/search/MagicSearchList.cpp @@ -57,7 +57,9 @@ void MagicSearchList::setSelf(QSharedPointer me) { auto friendCore = FriendCore::create(f); auto haveContact = std::find_if(mList.begin(), mList.end(), [friendCore](const QSharedPointer &item) { - return item.objectCast()->getDefaultAddress() == friendCore->getDefaultAddress(); + auto itemCore = item.objectCast(); + return itemCore->getDefaultAddress() == friendCore->getDefaultAddress() || + itemCore->getFriendModel()->getFriend() == friendCore->getFriendModel()->getFriend(); }); if (haveContact == mList.end()) { connect(friendCore.get(), &FriendCore::removed, this, qOverload(&MagicSearchList::remove)); diff --git a/Linphone/model/core/CoreModel.cpp b/Linphone/model/core/CoreModel.cpp index 63adb90a5..a79c097b7 100644 --- a/Linphone/model/core/CoreModel.cpp +++ b/Linphone/model/core/CoreModel.cpp @@ -410,7 +410,27 @@ void CoreModel::onVersionUpdateCheckResultReceived(const std::shared_ptr &core, const std::shared_ptr &friendList) { + // Hack because of SDK bug. Wait some times before removing friends. + // Note: shared pointers can be used with singleShot, they will be destroyed after removing lambda from timer. + QTimer::singleShot(500, [this, core, friendList]() { + emit friendListRemoved(core, friendList); + for (auto f : friendList->getFriends()) { + emit friendRemoved(f); + } + }); + /* TODO when SDK bug is fixed emit friendListRemoved(core, friendList); + qDebug() << "List removed: " << friendList->getDisplayName(); + for (auto l : core->getFriendsLists()) { + qDebug() << "Still have " << l->getDisplayName(); + } + for (auto f : friendList->getFriends()) { + auto linFriend = CoreModel::getInstance()->getCore()->findFriend(f->getAddress()); + if (linFriend) qDebug() << "Friend still exist: " << linFriend->getFriendList()->getDisplayName(); + emit friendRemoved(f); + } +*/ } diff --git a/Linphone/model/core/CoreModel.hpp b/Linphone/model/core/CoreModel.hpp index 96a0a1dda..bca43adcb 100644 --- a/Linphone/model/core/CoreModel.hpp +++ b/Linphone/model/core/CoreModel.hpp @@ -67,6 +67,7 @@ signals: void loggerInitialized(); void friendCreated(const std::shared_ptr &f); void friendRemoved(const std::shared_ptr &f); + void friendUpdated(const std::shared_ptr &f); void conferenceInfoCreated(const std::shared_ptr &confInfo); void unreadNotificationsChanged(); void requestFetchConfig(QString path); diff --git a/Linphone/model/friend/FriendModel.cpp b/Linphone/model/friend/FriendModel.cpp index e6a96b67b..840131aa3 100644 --- a/Linphone/model/friend/FriendModel.cpp +++ b/Linphone/model/friend/FriendModel.cpp @@ -22,6 +22,7 @@ #include "core/path/Paths.hpp" #include "model/core/CoreModel.hpp" +#include "model/tool/ToolModel.hpp" #include "tool/Utils.hpp" #include "tool/providers/AvatarProvider.hpp" #include @@ -56,20 +57,14 @@ FriendModel::FriendModel(const std::shared_ptr &contact, const }; connect(this, &FriendModel::givenNameChanged, updateFullName); connect(this, &FriendModel::familyNameChanged, updateFullName); - connect(this, &FriendModel::friendUpdated, [this]() { - if (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. - } - }); + + connect(this, &FriendModel::updated, [this]() { emit CoreModel::getInstance()->friendUpdated(mMonitor); }); + connect(CoreModel::getInstance().get(), &CoreModel::friendRemoved, this, &FriendModel::onRemoved); }; FriendModel::~FriendModel() { mustBeInLinphoneThread("~" + getClassName()); + mMonitor = nullptr; } std::shared_ptr FriendModel::getFriend() const { @@ -77,7 +72,7 @@ std::shared_ptr FriendModel::getFriend() const { } QDateTime FriendModel::getPresenceTimestamp() const { - if (mMonitor->getPresenceModel()) { + if (mMonitor && mMonitor->getPresenceModel()) { time_t timestamp = mMonitor->getPresenceModel()->getLatestActivityTimestamp(); if (timestamp == -1) return QDateTime(); else return QDateTime::fromMSecsSinceEpoch(timestamp * 1000); @@ -85,6 +80,7 @@ QDateTime FriendModel::getPresenceTimestamp() const { } void FriendModel::setAddress(const std::shared_ptr &address) { + if (!mMonitor) return; if (address) { mMonitor->setAddress(address); emit defaultAddressChanged(); @@ -96,6 +92,7 @@ std::list> FriendModel::getPhoneNum } void FriendModel::appendPhoneNumber(const std::shared_ptr &number) { + if (!mMonitor) return; if (number) { mMonitor->addPhoneNumberWithLabel(number); emit phoneNumbersChanged(); @@ -103,12 +100,14 @@ void FriendModel::appendPhoneNumber(const std::shared_ptr> &numbers) { + if (!mMonitor) return; for (auto &num : numbers) if (num) mMonitor->addPhoneNumberWithLabel(num); emit phoneNumbersChanged(); } void FriendModel::resetPhoneNumbers(const std::list> &numbers) { + if (!mMonitor) return; for (auto &num : mMonitor->getPhoneNumbers()) mMonitor->removePhoneNumber(num); for (auto &num : numbers) @@ -128,10 +127,11 @@ void FriendModel::clearPhoneNumbers() { } std::list> FriendModel::getAddresses() const { - return mMonitor->getAddresses(); + return mMonitor ? mMonitor->getAddresses() : std::list>(); } void FriendModel::appendAddress(const std::shared_ptr &addr) { + if (!mMonitor) return; if (addr) { mMonitor->addAddress(addr); emit addressesChanged(); @@ -139,12 +139,14 @@ void FriendModel::appendAddress(const std::shared_ptr &addr) } void FriendModel::appendAddresses(const std::list> &addresses) { + if (!mMonitor) return; for (auto &addr : addresses) if (addr) mMonitor->addAddress(addr); emit addressesChanged(); } void FriendModel::resetAddresses(const std::list> &addresses) { + if (!mMonitor) return; for (auto &addr : mMonitor->getAddresses()) mMonitor->removeAddress(addr); for (auto &addr : addresses) @@ -153,6 +155,7 @@ void FriendModel::resetAddresses(const std::list &addr) { + if (!mMonitor) return; if (addr) { mMonitor->removeAddress(addr); emit addressesChanged(); @@ -160,6 +163,7 @@ void FriendModel::removeAddress(const std::shared_ptr &addr) } void FriendModel::clearAddresses() { + if (!mMonitor) return; for (auto &addr : mMonitor->getAddresses()) if (addr) mMonitor->removeAddress(addr); emit addressesChanged(); @@ -178,6 +182,7 @@ void FriendModel::setFullName(const QString &name) { } QString FriendModel::getName() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -188,6 +193,7 @@ QString FriendModel::getName() const { } void FriendModel::setName(const QString &name) { + if (!mMonitor) return; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -197,6 +203,7 @@ void FriendModel::setName(const QString &name) { } QString FriendModel::getGivenName() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -207,6 +214,7 @@ QString FriendModel::getGivenName() const { } void FriendModel::setGivenName(const QString &name) { + if (!mMonitor) return; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -219,6 +227,7 @@ void FriendModel::setGivenName(const QString &name) { } QString FriendModel::getFamilyName() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -229,6 +238,7 @@ QString FriendModel::getFamilyName() const { } void FriendModel::setFamilyName(const QString &name) { + if (!mMonitor) return; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -241,6 +251,7 @@ void FriendModel::setFamilyName(const QString &name) { } QString FriendModel::getOrganization() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -251,6 +262,7 @@ QString FriendModel::getOrganization() const { } void FriendModel::setOrganization(const QString &orga) { + if (!mMonitor) return; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -263,6 +275,7 @@ void FriendModel::setOrganization(const QString &orga) { } QString FriendModel::getJob() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -273,6 +286,7 @@ QString FriendModel::getJob() const { } void FriendModel::setJob(const QString &job) { + if (!mMonitor) return; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -285,10 +299,11 @@ void FriendModel::setJob(const QString &job) { } bool FriendModel::getStarred() const { - return mMonitor->getStarred(); + return mMonitor ? mMonitor->getStarred() : false; } void FriendModel::setStarred(bool starred) { + if (!mMonitor) return; mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mMonitor->setStarred(starred); emit starredChanged(starred); @@ -298,6 +313,7 @@ void FriendModel::onPresenceReceived(const std::shared_ptr &co } QString FriendModel::getPictureUri() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -308,6 +324,7 @@ QString FriendModel::getPictureUri() const { } QString FriendModel::getVCardAsString() const { + if (!mMonitor) return ""; auto vcard = mMonitor->getVcard(); bool created = false; if (!vcard) { @@ -318,20 +335,21 @@ QString FriendModel::getVCardAsString() const { } std::list> FriendModel::getDevices() const { - return mMonitor->getDevices(); + return mMonitor ? mMonitor->getDevices() : std::list>(); } linphone::SecurityLevel FriendModel::getSecurityLevel() const { - return mMonitor->getSecurityLevel(); + return mMonitor ? mMonitor->getSecurityLevel() : linphone::SecurityLevel::None; } linphone::SecurityLevel FriendModel::getSecurityLevelForAddress(const std::shared_ptr address) const { - return mMonitor->getSecurityLevelForAddress(address); + return mMonitor ? mMonitor->getSecurityLevelForAddress(address) : linphone::SecurityLevel::None; } void FriendModel::setPictureUri(const QString &uri) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + if (!mMonitor) return; auto oldPictureUri = Utils::coreStringToAppString(mMonitor->getPhoto()); if (!oldPictureUri.isEmpty()) { QString appPrefix = QStringLiteral("image://%1/").arg(AvatarProvider::ProviderId); @@ -344,3 +362,42 @@ void FriendModel::setPictureUri(const QString &uri) { mMonitor->setPhoto(Utils::appStringToCoreString(uri)); emit pictureUriChanged(uri); } + +bool FriendModel::isThisFriend(const std::shared_ptr &data) { + if (!mMonitor) return false; + auto fAddress = mMonitor->getAddress(); + if (!fAddress) return false; + bool isThisFriend = false; + for (auto f : data->getAddresses()) { + if (f->weakEqual(fAddress)) { + isThisFriend = true; + break; + } + } + return isThisFriend; +} + +void FriendModel::remove() { + if (!mMonitor) return; + auto temp = mMonitor; + temp->remove(); // mMonitor become null + emit CoreModel::getInstance()->friendRemoved(temp); +} + +void FriendModel::onUpdated(const std::shared_ptr &data) { + if (isThisFriend(data)) { + emit givenNameChanged(getGivenName()); + emit familyNameChanged(getFamilyName()); + emit organizationChanged(getOrganization()); + emit jobChanged(getJob()); + emit pictureUriChanged(getPictureUri()); + emit updated(); + } +}; + +void FriendModel::onRemoved(const std::shared_ptr &data) { + if (data && isThisFriend(data)) { + setMonitor(nullptr); + emit removed(); + } +}; diff --git a/Linphone/model/friend/FriendModel.hpp b/Linphone/model/friend/FriendModel.hpp index 040f26de3..c667bf061 100644 --- a/Linphone/model/friend/FriendModel.hpp +++ b/Linphone/model/friend/FriendModel.hpp @@ -59,7 +59,6 @@ public: linphone::SecurityLevel getSecurityLevel() const; linphone::SecurityLevel getSecurityLevelForAddress(const std::shared_ptr address) const; -protected: void setAddress(const std::shared_ptr &address); void appendPhoneNumber(const std::shared_ptr &number); void appendPhoneNumbers(const std::list> &numbers); @@ -83,6 +82,13 @@ protected: void setPictureUri(const QString &uri); void setStarred(bool starred); + void remove(); + + bool isThisFriend(const std::shared_ptr &data); + + void onUpdated(const std::shared_ptr &data); + void onRemoved(const std::shared_ptr &data); + QString mFullName; signals: @@ -98,7 +104,8 @@ signals: void organizationChanged(const QString &orga); void jobChanged(const QString &job); void presenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp); - void friendUpdated(); + void updated(); + void removed(); private: DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/model/listener/Listener.hpp b/Linphone/model/listener/Listener.hpp index dcd51838d..c29d472ec 100644 --- a/Linphone/model/listener/Listener.hpp +++ b/Linphone/model/listener/Listener.hpp @@ -45,6 +45,7 @@ public: } ~Listener() { setSelf(nullptr); + setMonitor(nullptr); } virtual void onRemoveListener() { setSelf(nullptr); diff --git a/Linphone/model/object/VariantObject.hpp b/Linphone/model/object/VariantObject.hpp index d35719d72..6ae2f9a54 100644 --- a/Linphone/model/object/VariantObject.hpp +++ b/Linphone/model/object/VariantObject.hpp @@ -48,14 +48,22 @@ public: } template void makeUpdate(Sender sender, SenderClass signal) { - mConnection->makeConnectToModel( - sender, signal, [this]() { mConnection->invokeToCore([this]() { mCoreObject->requestValue(); }); }); + mConnection->makeConnectToModel(sender, signal, [this]() { invokeRequestValue(); }); } + template + void makeUpdateCond(Sender sender, SenderSignal signal, ReceiverSlot slot) { + mConnection->makeConnectToModel(sender, signal, slot); + } + QString mName; // usefull to know what is this VariantObject QVariant getValue() const; void requestValue(); void setDefaultValue(QVariant value); + void invokeRequestValue() { + mConnection->invokeToCore([this]() { mCoreObject->requestValue(); }); + } + QSharedPointer mCoreObject, mModelObject; QSharedPointer> mConnection; signals: diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 10c306997..6ec5bd972 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -358,6 +358,13 @@ VariantObject *Utils::findAvatarByAddress(const QString &address) { if (linFriend) avatar = Utils::coreStringToAppString(linFriend->getPhoto()); return QVariant(avatar); }); + // Rebuild avatar if needed + auto updateValue = [data, address](const std::shared_ptr &f) -> void { + if (f && f->getAddress()->weakEqual(ToolModel::interpretUrl(address))) data->invokeRequestValue(); + }; + data->makeUpdateCond(CoreModel::getInstance().get(), &CoreModel::friendCreated, updateValue); + data->makeUpdateCond(CoreModel::getInstance().get(), &CoreModel::friendRemoved, updateValue); + data->makeUpdateCond(CoreModel::getInstance().get(), &CoreModel::friendUpdated, updateValue); data->requestValue(); return data; } @@ -365,12 +372,18 @@ VariantObject *Utils::findAvatarByAddress(const QString &address) { VariantObject *Utils::findFriendByAddress(const QString &address) { VariantObject *data = new VariantObject("findFriendByAddress"); if (!data) return nullptr; - data->makeRequest([address]() { + data->makeRequest([data, address]() { auto linFriend = ToolModel::findFriendByAddress(address); if (!linFriend) return QVariant(); auto friendCore = FriendCore::create(linFriend); + connect(friendCore.get(), &FriendCore::removed, data, &VariantObject::invokeRequestValue); return QVariant::fromValue(new FriendGui(friendCore)); }); + // Rebuild friend if needed + auto updateValue = [data, address](const std::shared_ptr &f) -> void { + if (f->getAddress()->weakEqual(ToolModel::interpretUrl(address))) data->invokeRequestValue(); + }; + data->makeUpdateCond(CoreModel::getInstance().get(), &CoreModel::friendCreated, updateValue); // New Friend data->requestValue(); return data; } diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 009b71ccd..3bcc54108 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -307,13 +307,7 @@ AbstractMainPage { anchors.topMargin: 5 * DefaultStyle.dp anchors.bottomMargin: 5 * DefaultStyle.dp visible: !!modelData - Connections{ - target: modelData?.core - // Update contact with the new friend. - function onFriendAdded(){ - historyAvatar.contactObj = UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) - } - } + RowLayout { z: 1 anchors.fill: parent @@ -323,7 +317,7 @@ AbstractMainPage { Avatar { id: historyAvatar property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) - contact: contactObj && contactObj.value || null + contact: contactObj?.value || null _address: modelData.core.remoteAddress width: 45 * DefaultStyle.dp height: 45 * DefaultStyle.dp @@ -337,7 +331,7 @@ AbstractMainPage { id: friendAddress Layout.fillWidth: true maximumLineCount: 1 - text: modelData.core.displayName + text: historyAvatar.displayNameVal font { pixelSize: 14 * DefaultStyle.dp weight: 400 * DefaultStyle.dp @@ -660,18 +654,18 @@ AbstractMainPage { anchors.topMargin: 45 * DefaultStyle.dp anchors.bottomMargin: 45 * DefaultStyle.dp visible: mainItem.selectedRowHistoryGui != undefined - property var contactObj: UtilsCpp.findFriendByAddress(contactAddress) + + property var contactObj: UtilsCpp.findFriendByAddress(specificAddress) + contact: contactObj && contactObj.value || null conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || "" - + buttonContent: PopupButton { id: detailOptions anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter popup.x: width - property var friendGuiObj: UtilsCpp.findFriendByAddress(contactDetail.contactAddress) - property var friendGui: friendGuiObj ? friendGuiObj.value : null popup.contentItem: FocusScope { implicitHeight: detailsButtons.implicitHeight implicitWidth: detailsButtons.implicitWidth @@ -690,10 +684,10 @@ AbstractMainPage { icon.source: AppIcons.plusCircle icon.width: 32 * DefaultStyle.dp icon.height: 32 * DefaultStyle.dp - visible: SettingsCpp.syncLdapContacts || !detailOptions.friendGui?.core?.isLdap + visible: SettingsCpp.syncLdapContacts || !contactDetail.contact?.core?.isLdap onClicked: { detailOptions.close() - if (detailOptions.friendGui) mainWindow.displayContactPage(contactDetail.contactAddress) + if (contactDetail.contact) mainWindow.displayContactPage(contactDetail.contactAddress) else mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress) } }