diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dfbe47d54..1083e04c2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -58,6 +58,7 @@ set(SOURCES src/components/camera/Camera.cpp src/components/chat/ChatModel.cpp src/components/chat/ChatProxyModel.cpp + src/components/contact/ContactObserver.cpp src/components/contact/ContactModel.cpp src/components/contact/VcardModel.cpp src/components/contacts/ContactsListModel.cpp @@ -66,7 +67,6 @@ set(SOURCES src/components/notifier/Notifier.cpp src/components/settings/AccountSettingsModel.cpp src/components/settings/SettingsModel.cpp - src/components/sip-address/SipAddressModel.cpp src/components/sip-addresses/SipAddressesModel.cpp src/components/smart-search-bar/SmartSearchBarModel.cpp src/components/timeline/TimelineModel.cpp @@ -82,6 +82,7 @@ set(HEADERS src/components/camera/Camera.hpp src/components/chat/ChatModel.hpp src/components/chat/ChatProxyModel.hpp + src/components/contact/ContactObserver.hpp src/components/contact/ContactModel.hpp src/components/contact/VcardModel.hpp src/components/contacts/ContactsListModel.hpp @@ -91,7 +92,6 @@ set(HEADERS src/components/presence/Presence.hpp src/components/settings/AccountSettingsModel.hpp src/components/settings/SettingsModel.hpp - src/components/sip-address/SipAddressModel.hpp src/components/sip-addresses/SipAddressesModel.hpp src/components/smart-search-bar/SmartSearchBarModel.hpp src/components/timeline/TimelineModel.hpp diff --git a/tests/src/app/App.cpp b/tests/src/app/App.cpp index 468bd574d..8d2aa7c71 100644 --- a/tests/src/app/App.cpp +++ b/tests/src/app/App.cpp @@ -89,8 +89,8 @@ void App::registerTypes () { qmlRegisterUncreatableType( "Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable" ); - qmlRegisterUncreatableType( - "Linphone", 1, 0, "SipAddressModel", "SipAddressModel is uncreatable" + qmlRegisterUncreatableType( + "Linphone", 1, 0, "ContactObserver", "ContactObserver is uncreatable" ); qmlRegisterUncreatableType( "Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable" diff --git a/tests/src/components/contact/ContactObserver.cpp b/tests/src/components/contact/ContactObserver.cpp new file mode 100644 index 000000000..27415df10 --- /dev/null +++ b/tests/src/components/contact/ContactObserver.cpp @@ -0,0 +1,14 @@ +#include "../contact/ContactModel.hpp" + +#include "ContactObserver.hpp" + +// ============================================================================= + +ContactObserver::ContactObserver (const QString &sip_address) { + m_sip_address = sip_address; +} + +void ContactObserver::setContact (ContactModel *contact) { + m_contact = contact; + emit contactChanged(contact); +} diff --git a/tests/src/components/sip-address/SipAddressModel.hpp b/tests/src/components/contact/ContactObserver.hpp similarity index 62% rename from tests/src/components/sip-address/SipAddressModel.hpp rename to tests/src/components/contact/ContactObserver.hpp index 1476dc9e4..3c19e3a5f 100644 --- a/tests/src/components/sip-address/SipAddressModel.hpp +++ b/tests/src/components/contact/ContactObserver.hpp @@ -1,5 +1,5 @@ -#ifndef SIP_ADDRESS_MODEL_H_ -#define SIP_ADDRESS_MODEL_H_ +#ifndef CONTACT_OBSERVER_H_ +#define CONTACT_OBSERVER_H_ #include @@ -7,15 +7,17 @@ class ContactModel; -class SipAddressModel : public QObject { +class ContactObserver : public QObject { + friend class SipAddressesModel; + Q_OBJECT; Q_PROPERTY(QString sipAddress READ getSipAddress CONSTANT); Q_PROPERTY(ContactModel * contact READ getContact NOTIFY contactChanged); public: - SipAddressModel (); - ~SipAddressModel () = default; + ContactObserver (const QString &sip_address); + ~ContactObserver () = default; ContactModel *getContact () const { return m_contact; @@ -29,10 +31,12 @@ private: return m_sip_address; } + void setContact (ContactModel *contact); + QString m_sip_address; ContactModel *m_contact = nullptr; }; -Q_DECLARE_METATYPE(SipAddressModel *); +Q_DECLARE_METATYPE(ContactObserver *); -#endif // SIP_ADDRESS_MODEL_H_ +#endif // CONTACT_OBSERVER_H_ diff --git a/tests/src/components/sip-address/SipAddressModel.cpp b/tests/src/components/sip-address/SipAddressModel.cpp deleted file mode 100644 index 5ceaef73c..000000000 --- a/tests/src/components/sip-address/SipAddressModel.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "../contact/ContactModel.hpp" - -#include "SipAddressModel.hpp" - -// ============================================================================= - -SipAddressModel::SipAddressModel () { - // TODO -} diff --git a/tests/src/components/sip-addresses/SipAddressesModel.cpp b/tests/src/components/sip-addresses/SipAddressesModel.cpp index 4466b61ab..dd138ccba 100644 --- a/tests/src/components/sip-addresses/SipAddressesModel.cpp +++ b/tests/src/components/sip-addresses/SipAddressesModel.cpp @@ -115,6 +115,24 @@ void SipAddressesModel::handleAllHistoryEntriesRemoved () { // ----------------------------------------------------------------------------- +ContactObserver *SipAddressesModel::getContactObserver (const QString &sip_address) { + ContactObserver *model = new ContactObserver(sip_address); + model->setContact(mapSipAddressToContact(sip_address)); + + m_observers.insert(sip_address, model); + QObject::connect( + model, &ContactObserver::destroyed, this, [this, model]() { + const QString &sip_address = model->getSipAddress(); + if (m_observers.remove(sip_address, model) == 0) + qWarning() << QStringLiteral("Unable to remove sip address `%1` from observers.").arg(sip_address); + } + ); + + return model; +} + +// ----------------------------------------------------------------------------- + bool SipAddressesModel::removeRow (int row, const QModelIndex &parent) { return removeRows(row, 1, parent); } @@ -130,6 +148,7 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren for (int i = 0; i < count; ++i) { const QVariantMap *map = m_refs.takeAt(row); QString sip_address = (*map)["sipAddress"].toString(); + qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); m_sip_addresses.remove(sip_address); } @@ -153,6 +172,8 @@ void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, c map["sipAddress"] = sip_address; map["contact"] = QVariant::fromValue(contact); + updateObservers(sip_address, contact); + int row = m_refs.count(); beginInsertRows(QModelIndex(), row, row); @@ -172,6 +193,8 @@ void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, c // Sip address exists, update contact. (*it)["contact"] = QVariant::fromValue(contact); + updateObservers(sip_address, contact); + int row = m_refs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); @@ -184,6 +207,8 @@ void SipAddressesModel::tryToRemoveSipAddress (const QString &sip_address) { return; } + updateObservers(sip_address, nullptr); + if (it->remove("contact") == 0) qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sip_address); @@ -250,3 +275,10 @@ void SipAddressesModel::fetchSipAddresses () { for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list) updateFromNewContact(contact); } + +void SipAddressesModel::updateObservers (const QString &sip_address, ContactModel *contact) { + for (auto &observer : m_observers.values(sip_address)) { + if (contact != observer->getContact()) + observer->setContact(contact); + } +} diff --git a/tests/src/components/sip-addresses/SipAddressesModel.hpp b/tests/src/components/sip-addresses/SipAddressesModel.hpp index 2db68dd84..0df32bd8a 100644 --- a/tests/src/components/sip-addresses/SipAddressesModel.hpp +++ b/tests/src/components/sip-addresses/SipAddressesModel.hpp @@ -4,6 +4,7 @@ #include #include "../contact/ContactModel.hpp" +#include "../contact/ContactObserver.hpp" // ============================================================================= @@ -23,6 +24,8 @@ public slots: ContactModel *mapSipAddressToContact (const QString &sip_address) const; void handleAllHistoryEntriesRemoved (); + ContactObserver *getContactObserver (const QString &sip_address); + private: bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; @@ -33,8 +36,12 @@ private: void fetchSipAddresses (); + void updateObservers (const QString &sip_address, ContactModel *contact); + QHash m_sip_addresses; QList m_refs; + + QMultiHash m_observers; }; #endif // SIP_ADDRESSES_MODEL_H_ diff --git a/tests/ui/modules/Linphone/Chat/Chat.qml b/tests/ui/modules/Linphone/Chat/Chat.qml index 05f16513c..511b089f1 100644 --- a/tests/ui/modules/Linphone/Chat/Chat.qml +++ b/tests/ui/modules/Linphone/Chat/Chat.qml @@ -11,9 +11,7 @@ import Linphone.Styles 1.0 ColumnLayout { property alias proxyModel: chat.model - property var _contact: SipAddressesModel.mapSipAddressToContact( - proxyModel.sipAddress - ) || proxyModel.sipAddress + property var _contactObserver: SipAddressesModel.getContactObserver(proxyModel.sipAddress) // --------------------------------------------------------------------------- diff --git a/tests/ui/modules/Linphone/Chat/IncomingMessage.qml b/tests/ui/modules/Linphone/Chat/IncomingMessage.qml index f75a22282..62aa3077e 100644 --- a/tests/ui/modules/Linphone/Chat/IncomingMessage.qml +++ b/tests/ui/modules/Linphone/Chat/IncomingMessage.qml @@ -20,8 +20,8 @@ RowLayout { Avatar { anchors.centerIn: parent height: ChatStyle.entry.message.incoming.avatarSize - image: _contact.avatar - username: LinphoneUtils.getContactUsername(_contact) + image: _contactObserver.contact ? _contactObserver.contact.avatar : '' + username: LinphoneUtils.getContactUsername(_contactObserver.contact || _contactObserver.sipAddress) width: ChatStyle.entry.message.incoming.avatarSize } } diff --git a/tests/ui/views/App/Calls/Incall.qml b/tests/ui/views/App/Calls/Incall.qml index 7580b0216..89086593e 100644 --- a/tests/ui/views/App/Calls/Incall.qml +++ b/tests/ui/views/App/Calls/Incall.qml @@ -16,9 +16,7 @@ Rectangle { property bool isVideoCall: false property string sipAddress - property var _contact: SipAddressesModel.mapSipAddressToContact( - sipAddress - ) || sipAddress + property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress) // --------------------------------------------------------------------------- @@ -58,7 +56,7 @@ Rectangle { anchors.centerIn: parent horizontalTextAlignment: Text.AlignHCenter sipAddress: call.sipAddress - username: LinphoneUtils.getContactUsername(_contact) + username: LinphoneUtils.getContactUsername(_contactObserver.contact || call.sipAddress) height: parent.height width: parent.width - cameraActions.width - callQuality.width - 150 @@ -110,7 +108,7 @@ Rectangle { } backgroundColor: StartingCallStyle.avatar.backgroundColor - image: _contact.vcard.avatar + image: _contactObserver.contact ? _contactObserver.contact.vcard.avatar : '' username: contactDescription.username height: _computeAvatarSize()