Propagate friend creations/deletion to allow display name updating.

This commit is contained in:
Julien Wadel 2025-01-15 11:04:07 +01:00
parent 4a666035f6
commit b46c4d16f2
14 changed files with 218 additions and 84 deletions

View file

@ -93,42 +93,44 @@ void CallHistoryCore::setSelf(QSharedPointer<CallHistoryCore> me) {
});
});
}
if (!ToolModel::findFriendByAddress(mRemoteAddress)) {
mCoreModelConnection->makeConnectToModel(
&CoreModel::friendCreated,
[this, remoteAddress = mRemoteAddress](const std::shared_ptr<linphone::Friend> &f) {
auto friendModel = Utils::makeQObject_ptr<FriendModel>(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<SafeConnection<CallHistoryCore, FriendModel>>(
new SafeConnection<CallHistoryCore, FriendModel>(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<linphone::Friend> &updatedFriend) {
auto friendModel = Utils::makeQObject_ptr<FriendModel>(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<SafeConnection<CallHistoryCore, FriendModel>>(
new SafeConnection<CallHistoryCore, FriendModel>(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<linphone::Friend> &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();
}
};

View file

@ -55,6 +55,8 @@ public:
QString getDuration() const;
void setDuration(const QString &duration);
void onRemoved(const std::shared_ptr<linphone::Friend> &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:

View file

@ -125,6 +125,11 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
if (mFriendModel) {
mFriendModelConnection = QSharedPointer<SafeConnection<FriendCore, FriendModel>>(
new SafeConnection<FriendCore, FriendModel>(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<FriendModel> model) const {
model->setJob(mJob);
model->setPictureUri(mPictureUri);
model->getFriend()->done();
emit model->friendUpdated();
emit model->updated();
}
void FriendCore::writeFromModel(const std::shared_ptr<FriendModel> &model) {
@ -594,12 +599,7 @@ void FriendCore::writeFromModel(const std::shared_ptr<FriendModel> &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=<URL> &
// CardDAV
}
std::shared_ptr<FriendModel> FriendCore::getFriendModel() {
return mFriendModel;
}

View file

@ -148,6 +148,8 @@ public:
bool isLdap() const;
bool getReadOnly() const;
std::shared_ptr<FriendModel> getFriendModel();
Q_INVOKABLE void remove();
Q_INVOKABLE void save();
Q_INVOKABLE void undo();
@ -157,7 +159,7 @@ protected:
void resetAddresses(QList<QVariant> newList);
signals:
void contactUpdated();
void friendUpdated();
void givenNameChanged(QString name);
void familyNameChanged(QString name);
void fullNameChanged(QString name);

View file

@ -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;
}

View file

@ -57,7 +57,9 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
auto friendCore = FriendCore::create(f);
auto haveContact =
std::find_if(mList.begin(), mList.end(), [friendCore](const QSharedPointer<QObject> &item) {
return item.objectCast<FriendCore>()->getDefaultAddress() == friendCore->getDefaultAddress();
auto itemCore = item.objectCast<FriendCore>();
return itemCore->getDefaultAddress() == friendCore->getDefaultAddress() ||
itemCore->getFriendModel()->getFriend() == friendCore->getFriendModel()->getFriend();
});
if (haveContact == mList.end()) {
connect(friendCore.get(), &FriendCore::removed, this, qOverload<QObject *>(&MagicSearchList::remove));

View file

@ -410,7 +410,27 @@ void CoreModel::onVersionUpdateCheckResultReceived(const std::shared_ptr<linphon
const std::string &url) {
emit versionUpdateCheckResultReceived(core, result, version, url);
}
void CoreModel::onFriendListRemoved(const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::FriendList> &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);
}
*/
}

View file

@ -67,6 +67,7 @@ signals:
void loggerInitialized();
void friendCreated(const std::shared_ptr<linphone::Friend> &f);
void friendRemoved(const std::shared_ptr<linphone::Friend> &f);
void friendUpdated(const std::shared_ptr<linphone::Friend> &f);
void conferenceInfoCreated(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
void unreadNotificationsChanged();
void requestFetchConfig(QString path);

View file

@ -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 <QDebug>
@ -56,20 +57,14 @@ FriendModel::FriendModel(const std::shared_ptr<linphone::Friend> &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<linphone::Friend> FriendModel::getFriend() const {
@ -77,7 +72,7 @@ std::shared_ptr<linphone::Friend> 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<linphone::Address> &address) {
if (!mMonitor) return;
if (address) {
mMonitor->setAddress(address);
emit defaultAddressChanged();
@ -96,6 +92,7 @@ std::list<std::shared_ptr<linphone::FriendPhoneNumber>> FriendModel::getPhoneNum
}
void FriendModel::appendPhoneNumber(const std::shared_ptr<linphone::FriendPhoneNumber> &number) {
if (!mMonitor) return;
if (number) {
mMonitor->addPhoneNumberWithLabel(number);
emit phoneNumbersChanged();
@ -103,12 +100,14 @@ void FriendModel::appendPhoneNumber(const std::shared_ptr<linphone::FriendPhoneN
}
void FriendModel::appendPhoneNumbers(const std::list<std::shared_ptr<linphone::FriendPhoneNumber>> &numbers) {
if (!mMonitor) return;
for (auto &num : numbers)
if (num) mMonitor->addPhoneNumberWithLabel(num);
emit phoneNumbersChanged();
}
void FriendModel::resetPhoneNumbers(const std::list<std::shared_ptr<linphone::FriendPhoneNumber>> &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<std::shared_ptr<linphone::Address>> FriendModel::getAddresses() const {
return mMonitor->getAddresses();
return mMonitor ? mMonitor->getAddresses() : std::list<std::shared_ptr<linphone::Address>>();
}
void FriendModel::appendAddress(const std::shared_ptr<linphone::Address> &addr) {
if (!mMonitor) return;
if (addr) {
mMonitor->addAddress(addr);
emit addressesChanged();
@ -139,12 +139,14 @@ void FriendModel::appendAddress(const std::shared_ptr<linphone::Address> &addr)
}
void FriendModel::appendAddresses(const std::list<std::shared_ptr<linphone::Address>> &addresses) {
if (!mMonitor) return;
for (auto &addr : addresses)
if (addr) mMonitor->addAddress(addr);
emit addressesChanged();
}
void FriendModel::resetAddresses(const std::list<std::shared_ptr<linphone::Address>> &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<std::shared_ptr<linphone::Addre
}
void FriendModel::removeAddress(const std::shared_ptr<linphone::Address> &addr) {
if (!mMonitor) return;
if (addr) {
mMonitor->removeAddress(addr);
emit addressesChanged();
@ -160,6 +163,7 @@ void FriendModel::removeAddress(const std::shared_ptr<linphone::Address> &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<linphone::Friend> &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<std::shared_ptr<linphone::FriendDevice>> FriendModel::getDevices() const {
return mMonitor->getDevices();
return mMonitor ? mMonitor->getDevices() : std::list<std::shared_ptr<linphone::FriendDevice>>();
}
linphone::SecurityLevel FriendModel::getSecurityLevel() const {
return mMonitor->getSecurityLevel();
return mMonitor ? mMonitor->getSecurityLevel() : linphone::SecurityLevel::None;
}
linphone::SecurityLevel
FriendModel::getSecurityLevelForAddress(const std::shared_ptr<linphone::Address> 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<linphone::Friend> &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<linphone::Friend> &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<linphone::Friend> &data) {
if (data && isThisFriend(data)) {
setMonitor(nullptr);
emit removed();
}
};

View file

@ -59,7 +59,6 @@ public:
linphone::SecurityLevel getSecurityLevel() const;
linphone::SecurityLevel getSecurityLevelForAddress(const std::shared_ptr<linphone::Address> address) const;
protected:
void setAddress(const std::shared_ptr<linphone::Address> &address);
void appendPhoneNumber(const std::shared_ptr<linphone::FriendPhoneNumber> &number);
void appendPhoneNumbers(const std::list<std::shared_ptr<linphone::FriendPhoneNumber>> &numbers);
@ -83,6 +82,13 @@ protected:
void setPictureUri(const QString &uri);
void setStarred(bool starred);
void remove();
bool isThisFriend(const std::shared_ptr<linphone::Friend> &data);
void onUpdated(const std::shared_ptr<linphone::Friend> &data);
void onRemoved(const std::shared_ptr<linphone::Friend> &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

View file

@ -45,6 +45,7 @@ public:
}
~Listener() {
setSelf(nullptr);
setMonitor(nullptr);
}
virtual void onRemoveListener() {
setSelf(nullptr);

View file

@ -48,14 +48,22 @@ public:
}
template <typename Sender, typename SenderClass>
void makeUpdate(Sender sender, SenderClass signal) {
mConnection->makeConnectToModel(
sender, signal, [this]() { mConnection->invokeToCore([this]() { mCoreObject->requestValue(); }); });
mConnection->makeConnectToModel(sender, signal, [this]() { invokeRequestValue(); });
}
template <typename Sender, typename SenderSignal, typename ReceiverSlot>
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<SafeObject> mCoreObject, mModelObject;
QSharedPointer<SafeConnection<SafeObject, SafeObject>> mConnection;
signals:

View file

@ -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<linphone::Friend> &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<linphone::Friend> &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;
}

View file

@ -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)
}
}