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());
} else {
mRemoteAddress = Utils::coreStringToAppString(addr->asStringUriOnly());
mDisplayName = ToolModel::getDisplayName(Utils::coreStringToAppString(addr->asStringUriOnly()));
auto inFriend = Utils::findFriendByAddress(mRemoteAddress);
if (inFriend) {
auto friendGui = inFriend->getValue().value<FriendGui *>();
if (friendGui) mDisplayName = friendGui->getCore()->getFullName();
}
auto linphoneFriend = ToolModel::findFriendByAddress(mRemoteAddress);
if (linphoneFriend) {
mFriendModel = Utils::makeQObject_ptr<FriendModel>(linphoneFriend);
mDisplayName = mFriendModel->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);
mCoreModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>>(
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)) {
mCoreModelConnection->makeConnectToModel(
&CoreModel::friendCreated,
[this, remoteAddress = mRemoteAddress](const std::shared_ptr<linphone::Friend> &f) {
auto inFriend = Utils::findFriendByAddress(remoteAddress);
QString displayName;
if (inFriend) {
auto friendGui = inFriend->getValue().value<FriendGui *>();
if (friendGui) displayName = friendGui->getCore()->getFullName();
}
if (!displayName.isEmpty()) {
mCoreModelConnection->invokeToCore([this, displayName]() {
if (displayName != mDisplayName) {
mDisplayName = displayName;
emit displayNameChanged();
}
auto friendModel = Utils::makeQObject_ptr<FriendModel>(f);
auto displayName = friendModel->getFullName();
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();
}
});
});
}
}

View file

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

View file

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

View file

@ -66,6 +66,7 @@ public:
signals:
void loggerInitialized();
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 conferenceInfoCreated(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
void unreadNotificationsChanged();

View file

@ -21,6 +21,7 @@
#include "FriendModel.hpp"
#include "core/path/Paths.hpp"
#include "model/core/CoreModel.hpp"
#include "tool/Utils.hpp"
#include "tool/providers/AvatarProvider.hpp"
#include <QDebug>
@ -41,6 +42,31 @@ FriendModel::FriendModel(const std::shared_ptr<linphone::Friend> &contact, const
});
if (!contact->getName().empty() || !name.isEmpty())
mMonitor->setName(contact->getName().empty() ? Utils::appStringToCoreString(name) : contact->getName());
auto vcard = contact->getVcard();
if (vcard) {
mFullName = Utils::coreStringToAppString(vcard->getFullName());
}
if (mFullName.isEmpty()) mFullName = Utils::coreStringToAppString(contact->getName());
if (mFullName.isEmpty()) mFullName = Utils::coreStringToAppString(contact->getOrganization());
auto updateFullName = [this] {
QStringList fullName;
fullName << getGivenName() << getFamilyName();
fullName.removeAll("");
setFullName(fullName.join(" "));
};
connect(this, &FriendModel::givenNameChanged, updateFullName);
connect(this, &FriendModel::familyNameChanged, updateFullName);
connect(CoreModel::getInstance().get(), &CoreModel::friendUpdated,
[this](const std::shared_ptr<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() {
@ -140,6 +166,18 @@ void FriendModel::clearAddresses() {
emit addressesChanged();
}
QString FriendModel::getFullName() const {
if (mFullName.isEmpty()) return getGivenName() + " " + getFamilyName();
else return mFullName;
}
void FriendModel::setFullName(const QString &name) {
if (mFullName != name) {
mFullName = name;
emit fullNameChanged(name);
}
}
QString FriendModel::getName() const {
auto vcard = mMonitor->getVcard();
bool created = false;

View file

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

View file

@ -400,9 +400,6 @@ AbstractMainPage {
positionViewAtIndex(currentIndex, ListView.Visible)
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
}
onCountChanged: {
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
}
onVisibleChanged: {
if (!visible) currentIndex = -1
}
@ -654,12 +651,7 @@ AbstractMainPage {
contact: contactObj && contactObj.value || null
conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null
specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || ""
Connections {
target: mainItem.selectedRowHistoryGui?.core ? mainItem.selectedRowHistoryGui.core : null
onDisplayNameChanged: {
mainItem.onSelectedRowHistoryGuiChanged() // to cover displayName & Avatar.
}
}
buttonContent: PopupButton {
id: detailOptions
anchors.right: parent.right