mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
Propagate friend creations/deletion to allow display name updating.
This commit is contained in:
parent
4a666035f6
commit
b46c4d16f2
14 changed files with 218 additions and 84 deletions
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
}
|
||||
~Listener() {
|
||||
setSelf(nullptr);
|
||||
setMonitor(nullptr);
|
||||
}
|
||||
virtual void onRemoveListener() {
|
||||
setSelf(nullptr);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue