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.
This commit is contained in:
Julien Wadel 2024-11-21 16:36:35 +01:00
parent 969b59015b
commit 345c90d244
8 changed files with 94 additions and 41 deletions

View file

@ -62,12 +62,11 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr<linphone::CallLog> &callL
mDisplayName = Utils::coreStringToAppString(confinfo->getSubject()); mDisplayName = Utils::coreStringToAppString(confinfo->getSubject());
} else { } else {
mRemoteAddress = Utils::coreStringToAppString(addr->asStringUriOnly()); mRemoteAddress = Utils::coreStringToAppString(addr->asStringUriOnly());
mDisplayName = ToolModel::getDisplayName(Utils::coreStringToAppString(addr->asStringUriOnly())); auto linphoneFriend = ToolModel::findFriendByAddress(mRemoteAddress);
auto inFriend = Utils::findFriendByAddress(mRemoteAddress); if (linphoneFriend) {
if (inFriend) { mFriendModel = Utils::makeQObject_ptr<FriendModel>(linphoneFriend);
auto friendGui = inFriend->getValue().value<FriendGui *>(); mDisplayName = mFriendModel->getFullName();
if (friendGui) mDisplayName = friendGui->getCore()->getFullName(); } else mDisplayName = ToolModel::getDisplayName(Utils::coreStringToAppString(addr->asStringUriOnly()));
}
} }
} }
@ -81,24 +80,44 @@ void CallHistoryCore::setSelf(QSharedPointer<CallHistoryCore> me) {
new SafeConnection<CallHistoryCore, CallHistoryModel>(me, mCallHistoryModel), &QObject::deleteLater); new SafeConnection<CallHistoryCore, CallHistoryModel>(me, mCallHistoryModel), &QObject::deleteLater);
mCoreModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>>( mCoreModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>>(
new SafeConnection<CallHistoryCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater); new SafeConnection<CallHistoryCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
if (mFriendModel) {
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 (!ToolModel::findFriendByAddress(mRemoteAddress)) { if (!ToolModel::findFriendByAddress(mRemoteAddress)) {
mCoreModelConnection->makeConnectToModel( mCoreModelConnection->makeConnectToModel(
&CoreModel::friendCreated, &CoreModel::friendCreated,
[this, remoteAddress = mRemoteAddress](const std::shared_ptr<linphone::Friend> &f) { [this, remoteAddress = mRemoteAddress](const std::shared_ptr<linphone::Friend> &f) {
auto inFriend = Utils::findFriendByAddress(remoteAddress); auto friendModel = Utils::makeQObject_ptr<FriendModel>(f);
QString displayName; auto displayName = friendModel->getFullName();
if (inFriend) { mCoreModelConnection->invokeToCore([this, friendModel, displayName]() {
auto friendGui = inFriend->getValue().value<FriendGui *>(); mFriendModel = friendModel;
if (friendGui) displayName = friendGui->getCore()->getFullName(); 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.isEmpty()) { });
mCoreModelConnection->invokeToCore([this, displayName]() { });
if (displayName != mDisplayName) { if (displayName != mDisplayName) {
mDisplayName = displayName; mDisplayName = displayName;
emit displayNameChanged(); emit displayNameChanged();
} }
}); });
}
}); });
} }
} }

View file

@ -30,6 +30,7 @@
#include <linphone++/linphone.hh> #include <linphone++/linphone.hh>
class CallHistoryModel; class CallHistoryModel;
class FriendModel;
class CallHistoryCore : public QObject, public AbstractObject { class CallHistoryCore : public QObject, public AbstractObject {
Q_OBJECT Q_OBJECT
@ -72,6 +73,8 @@ private:
QString mDuration; QString mDuration;
QSharedPointer<ConferenceInfoCore> mConferenceInfo = nullptr; QSharedPointer<ConferenceInfoCore> mConferenceInfo = nullptr;
std::shared_ptr<CallHistoryModel> mCallHistoryModel; std::shared_ptr<CallHistoryModel> mCallHistoryModel;
std::shared_ptr<FriendModel> mFriendModel;
QSharedPointer<SafeConnection<CallHistoryCore, FriendModel>> mFriendModelConnection;
QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>> mHistoryModelConnection; QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>> mHistoryModelConnection;
QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>> mCoreModelConnection;

View file

@ -60,6 +60,7 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool is
mConsolidatedPresence = LinphoneEnums::fromLinphone(contact->getConsolidatedPresence()); mConsolidatedPresence = LinphoneEnums::fromLinphone(contact->getConsolidatedPresence());
mPresenceTimestamp = mFriendModel->getPresenceTimestamp(); mPresenceTimestamp = mFriendModel->getPresenceTimestamp();
mPictureUri = Utils::coreStringToAppString(contact->getPhoto()); mPictureUri = Utils::coreStringToAppString(contact->getPhoto());
mFullName = mFriendModel->getFullName();
auto defaultAddress = contact->getAddress(); auto defaultAddress = contact->getAddress();
auto vcard = contact->getVcard(); auto vcard = contact->getVcard();
if (vcard) { if (vcard) {
@ -67,11 +68,8 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool is
mJob = Utils::coreStringToAppString(vcard->getJobTitle()); mJob = Utils::coreStringToAppString(vcard->getJobTitle());
mGivenName = Utils::coreStringToAppString(vcard->getGivenName()); mGivenName = Utils::coreStringToAppString(vcard->getGivenName());
mFamilyName = Utils::coreStringToAppString(vcard->getFamilyName()); mFamilyName = Utils::coreStringToAppString(vcard->getFamilyName());
mFullName = Utils::coreStringToAppString(vcard->getFullName());
mVCardString = Utils::coreStringToAppString(vcard->asVcard4String()); 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(); auto addresses = contact->getAddresses();
for (auto &address : addresses) { for (auto &address : addresses) {
@ -108,12 +106,6 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool is
mIsLdap = ToolModel::friendIsInFriendList(ToolModel::getLdapFriendList(), contact); mIsLdap = ToolModel::friendIsInFriendList(ToolModel::getLdapFriendList(), contact);
connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged); connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged);
connect(this, &FriendCore::phoneNumberChanged, &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) { FriendCore::FriendCore(const FriendCore &friendCore) {
@ -181,6 +173,9 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
mFriendModelConnection->makeConnectToModel(&FriendModel::organizationChanged, [this](const QString &orga) { mFriendModelConnection->makeConnectToModel(&FriendModel::organizationChanged, [this](const QString &orga) {
mFriendModelConnection->invokeToCore([this, orga]() { setOrganization(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->makeConnectToModel(&FriendModel::jobChanged, [this](const QString &job) {
mFriendModelConnection->invokeToCore([this, job]() { setJob(job); }); mFriendModelConnection->invokeToCore([this, job]() { setJob(job); });
}); });
@ -248,14 +243,14 @@ void FriendCore::reset(const FriendCore &contact) {
setGivenName(contact.getGivenName()); setGivenName(contact.getGivenName());
setFamilyName(contact.getFamilyName()); setFamilyName(contact.getFamilyName());
setOrganization(contact.getOrganization()); setOrganization(contact.getOrganization());
setFullName(contact.getFullName());
setJob(contact.getJob()); setJob(contact.getJob());
setPictureUri(contact.getPictureUri()); setPictureUri(contact.getPictureUri());
setIsSaved(mFriendModel != nullptr); setIsSaved(mFriendModel != nullptr);
} }
QString FriendCore::getFullName() const { QString FriendCore::getFullName() const {
if (mFullName.isEmpty()) return mGivenName + " " + mFamilyName; return mFullName;
else return mFullName;
} }
void FriendCore::setFullName(const QString &name) { void FriendCore::setFullName(const QString &name) {
@ -563,13 +558,14 @@ void FriendCore::writeIntoModel(std::shared_ptr<FriendModel> model) const {
phones.push_back(num); phones.push_back(num);
} }
model->resetPhoneNumbers(phones); model->resetPhoneNumbers(phones);
model->setGivenName(mGivenName); model->setGivenName(mGivenName);
model->setFamilyName(mFamilyName); model->setFamilyName(mFamilyName);
model->setOrganization(mOrganization); model->setOrganization(mOrganization);
model->setFullName(mFullName);
model->setJob(mJob); model->setJob(mJob);
model->setPictureUri(mPictureUri); model->setPictureUri(mPictureUri);
model->getFriend()->done(); model->getFriend()->done();
emit CoreModel::getInstance()->friendUpdated(model->getFriend());
} }
void FriendCore::writeFromModel(const std::shared_ptr<FriendModel> &model) { void FriendCore::writeFromModel(const std::shared_ptr<FriendModel> &model) {

View file

@ -154,7 +154,6 @@ protected:
signals: signals:
void contactUpdated(); void contactUpdated();
void displayNameChanged();
void givenNameChanged(QString name); void givenNameChanged(QString name);
void familyNameChanged(QString name); void familyNameChanged(QString name);
void fullNameChanged(QString name); void fullNameChanged(QString name);

View file

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

View file

@ -21,6 +21,7 @@
#include "FriendModel.hpp" #include "FriendModel.hpp"
#include "core/path/Paths.hpp" #include "core/path/Paths.hpp"
#include "model/core/CoreModel.hpp"
#include "tool/Utils.hpp" #include "tool/Utils.hpp"
#include "tool/providers/AvatarProvider.hpp" #include "tool/providers/AvatarProvider.hpp"
#include <QDebug> #include <QDebug>
@ -41,6 +42,31 @@ FriendModel::FriendModel(const std::shared_ptr<linphone::Friend> &contact, const
}); });
if (!contact->getName().empty() || !name.isEmpty()) if (!contact->getName().empty() || !name.isEmpty())
mMonitor->setName(contact->getName().empty() ? Utils::appStringToCoreString(name) : contact->getName()); 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<linphone::Friend> &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() { FriendModel::~FriendModel() {
@ -140,6 +166,18 @@ void FriendModel::clearAddresses() {
emit addressesChanged(); 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 { QString FriendModel::getName() const {
auto vcard = mMonitor->getVcard(); auto vcard = mMonitor->getVcard();
bool created = false; bool created = false;

View file

@ -45,6 +45,7 @@ public:
QDateTime getPresenceTimestamp() const; QDateTime getPresenceTimestamp() const;
std::list<std::shared_ptr<linphone::FriendPhoneNumber>> getPhoneNumbers() const; std::list<std::shared_ptr<linphone::FriendPhoneNumber>> getPhoneNumbers() const;
std::list<std::shared_ptr<linphone::Address>> getAddresses() const; std::list<std::shared_ptr<linphone::Address>> getAddresses() const;
QString getFullName() const;
QString getName() const; QString getName() const;
QString getGivenName() const; QString getGivenName() const;
QString getFamilyName() const; QString getFamilyName() const;
@ -72,6 +73,7 @@ protected:
void removeAddress(const std::shared_ptr<linphone::Address> &addr); void removeAddress(const std::shared_ptr<linphone::Address> &addr);
void clearAddresses(); void clearAddresses();
void setFullName(const QString &name);
void setName(const QString &name); void setName(const QString &name);
void setGivenName(const QString &name); void setGivenName(const QString &name);
void setFamilyName(const QString &name); void setFamilyName(const QString &name);
@ -81,6 +83,8 @@ protected:
void setPictureUri(const QString &uri); void setPictureUri(const QString &uri);
void setStarred(bool starred); void setStarred(bool starred);
QString mFullName;
signals: signals:
void pictureUriChanged(const QString &uri); void pictureUriChanged(const QString &uri);
void starredChanged(bool starred); void starredChanged(bool starred);
@ -88,6 +92,7 @@ signals:
void defaultAddressChanged(); void defaultAddressChanged();
void phoneNumbersChanged(); void phoneNumbersChanged();
// void nameChanged(const QString &name); // void nameChanged(const QString &name);
void fullNameChanged(const QString &name);
void givenNameChanged(const QString &name); void givenNameChanged(const QString &name);
void familyNameChanged(const QString &name); void familyNameChanged(const QString &name);
void organizationChanged(const QString &orga); void organizationChanged(const QString &orga);

View file

@ -400,9 +400,6 @@ AbstractMainPage {
positionViewAtIndex(currentIndex, ListView.Visible) positionViewAtIndex(currentIndex, ListView.Visible)
mainItem.selectedRowHistoryGui = model.getAt(currentIndex) mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
} }
onCountChanged: {
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
}
onVisibleChanged: { onVisibleChanged: {
if (!visible) currentIndex = -1 if (!visible) currentIndex = -1
} }
@ -654,12 +651,7 @@ AbstractMainPage {
contact: contactObj && contactObj.value || null contact: contactObj && contactObj.value || null
conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null
specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || "" 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 { buttonContent: PopupButton {
id: detailOptions id: detailOptions
anchors.right: parent.right anchors.right: parent.right