Commit 9813baf1 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(app): add a `ContactObserver` component

parent ed17343d
...@@ -58,6 +58,7 @@ set(SOURCES ...@@ -58,6 +58,7 @@ set(SOURCES
src/components/camera/Camera.cpp src/components/camera/Camera.cpp
src/components/chat/ChatModel.cpp src/components/chat/ChatModel.cpp
src/components/chat/ChatProxyModel.cpp src/components/chat/ChatProxyModel.cpp
src/components/contact/ContactObserver.cpp
src/components/contact/ContactModel.cpp src/components/contact/ContactModel.cpp
src/components/contact/VcardModel.cpp src/components/contact/VcardModel.cpp
src/components/contacts/ContactsListModel.cpp src/components/contacts/ContactsListModel.cpp
...@@ -66,7 +67,6 @@ set(SOURCES ...@@ -66,7 +67,6 @@ set(SOURCES
src/components/notifier/Notifier.cpp src/components/notifier/Notifier.cpp
src/components/settings/AccountSettingsModel.cpp src/components/settings/AccountSettingsModel.cpp
src/components/settings/SettingsModel.cpp src/components/settings/SettingsModel.cpp
src/components/sip-address/SipAddressModel.cpp
src/components/sip-addresses/SipAddressesModel.cpp src/components/sip-addresses/SipAddressesModel.cpp
src/components/smart-search-bar/SmartSearchBarModel.cpp src/components/smart-search-bar/SmartSearchBarModel.cpp
src/components/timeline/TimelineModel.cpp src/components/timeline/TimelineModel.cpp
...@@ -82,6 +82,7 @@ set(HEADERS ...@@ -82,6 +82,7 @@ set(HEADERS
src/components/camera/Camera.hpp src/components/camera/Camera.hpp
src/components/chat/ChatModel.hpp src/components/chat/ChatModel.hpp
src/components/chat/ChatProxyModel.hpp src/components/chat/ChatProxyModel.hpp
src/components/contact/ContactObserver.hpp
src/components/contact/ContactModel.hpp src/components/contact/ContactModel.hpp
src/components/contact/VcardModel.hpp src/components/contact/VcardModel.hpp
src/components/contacts/ContactsListModel.hpp src/components/contacts/ContactsListModel.hpp
...@@ -91,7 +92,6 @@ set(HEADERS ...@@ -91,7 +92,6 @@ set(HEADERS
src/components/presence/Presence.hpp src/components/presence/Presence.hpp
src/components/settings/AccountSettingsModel.hpp src/components/settings/AccountSettingsModel.hpp
src/components/settings/SettingsModel.hpp src/components/settings/SettingsModel.hpp
src/components/sip-address/SipAddressModel.hpp
src/components/sip-addresses/SipAddressesModel.hpp src/components/sip-addresses/SipAddressesModel.hpp
src/components/smart-search-bar/SmartSearchBarModel.hpp src/components/smart-search-bar/SmartSearchBarModel.hpp
src/components/timeline/TimelineModel.hpp src/components/timeline/TimelineModel.hpp
......
...@@ -89,8 +89,8 @@ void App::registerTypes () { ...@@ -89,8 +89,8 @@ void App::registerTypes () {
qmlRegisterUncreatableType<ContactModel>( qmlRegisterUncreatableType<ContactModel>(
"Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable" "Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable"
); );
qmlRegisterUncreatableType<SipAddressModel>( qmlRegisterUncreatableType<ContactObserver>(
"Linphone", 1, 0, "SipAddressModel", "SipAddressModel is uncreatable" "Linphone", 1, 0, "ContactObserver", "ContactObserver is uncreatable"
); );
qmlRegisterUncreatableType<VcardModel>( qmlRegisterUncreatableType<VcardModel>(
"Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable" "Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable"
......
#include "../contact/ContactModel.hpp" #include "../contact/ContactModel.hpp"
#include "SipAddressModel.hpp" #include "ContactObserver.hpp"
// ============================================================================= // =============================================================================
SipAddressModel::SipAddressModel () { ContactObserver::ContactObserver (const QString &sip_address) {
// TODO m_sip_address = sip_address;
}
void ContactObserver::setContact (ContactModel *contact) {
m_contact = contact;
emit contactChanged(contact);
} }
#ifndef SIP_ADDRESS_MODEL_H_ #ifndef CONTACT_OBSERVER_H_
#define SIP_ADDRESS_MODEL_H_ #define CONTACT_OBSERVER_H_
#include <QObject> #include <QObject>
...@@ -7,15 +7,17 @@ ...@@ -7,15 +7,17 @@
class ContactModel; class ContactModel;
class SipAddressModel : public QObject { class ContactObserver : public QObject {
friend class SipAddressesModel;
Q_OBJECT; Q_OBJECT;
Q_PROPERTY(QString sipAddress READ getSipAddress CONSTANT); Q_PROPERTY(QString sipAddress READ getSipAddress CONSTANT);
Q_PROPERTY(ContactModel * contact READ getContact NOTIFY contactChanged); Q_PROPERTY(ContactModel * contact READ getContact NOTIFY contactChanged);
public: public:
SipAddressModel (); ContactObserver (const QString &sip_address);
~SipAddressModel () = default; ~ContactObserver () = default;
ContactModel *getContact () const { ContactModel *getContact () const {
return m_contact; return m_contact;
...@@ -29,10 +31,12 @@ private: ...@@ -29,10 +31,12 @@ private:
return m_sip_address; return m_sip_address;
} }
void setContact (ContactModel *contact);
QString m_sip_address; QString m_sip_address;
ContactModel *m_contact = nullptr; ContactModel *m_contact = nullptr;
}; };
Q_DECLARE_METATYPE(SipAddressModel *); Q_DECLARE_METATYPE(ContactObserver *);
#endif // SIP_ADDRESS_MODEL_H_ #endif // CONTACT_OBSERVER_H_
...@@ -115,6 +115,24 @@ void SipAddressesModel::handleAllHistoryEntriesRemoved () { ...@@ -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) { bool SipAddressesModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent); return removeRows(row, 1, parent);
} }
...@@ -130,6 +148,7 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren ...@@ -130,6 +148,7 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
const QVariantMap *map = m_refs.takeAt(row); const QVariantMap *map = m_refs.takeAt(row);
QString sip_address = (*map)["sipAddress"].toString(); QString sip_address = (*map)["sipAddress"].toString();
qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address);
m_sip_addresses.remove(sip_address); m_sip_addresses.remove(sip_address);
} }
...@@ -153,6 +172,8 @@ void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, c ...@@ -153,6 +172,8 @@ void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, c
map["sipAddress"] = sip_address; map["sipAddress"] = sip_address;
map["contact"] = QVariant::fromValue(contact); map["contact"] = QVariant::fromValue(contact);
updateObservers(sip_address, contact);
int row = m_refs.count(); int row = m_refs.count();
beginInsertRows(QModelIndex(), row, row); beginInsertRows(QModelIndex(), row, row);
...@@ -172,6 +193,8 @@ void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, c ...@@ -172,6 +193,8 @@ void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, c
// Sip address exists, update contact. // Sip address exists, update contact.
(*it)["contact"] = QVariant::fromValue(contact); (*it)["contact"] = QVariant::fromValue(contact);
updateObservers(sip_address, contact);
int row = m_refs.indexOf(&(*it)); int row = m_refs.indexOf(&(*it));
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0)); emit dataChanged(index(row, 0), index(row, 0));
...@@ -184,6 +207,8 @@ void SipAddressesModel::tryToRemoveSipAddress (const QString &sip_address) { ...@@ -184,6 +207,8 @@ void SipAddressesModel::tryToRemoveSipAddress (const QString &sip_address) {
return; return;
} }
updateObservers(sip_address, nullptr);
if (it->remove("contact") == 0) if (it->remove("contact") == 0)
qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sip_address); qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sip_address);
...@@ -250,3 +275,10 @@ void SipAddressesModel::fetchSipAddresses () { ...@@ -250,3 +275,10 @@ void SipAddressesModel::fetchSipAddresses () {
for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list) for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list)
updateFromNewContact(contact); 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);
}
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include "../contact/ContactModel.hpp" #include "../contact/ContactModel.hpp"
#include "../contact/ContactObserver.hpp"
// ============================================================================= // =============================================================================
...@@ -23,6 +24,8 @@ public slots: ...@@ -23,6 +24,8 @@ public slots:
ContactModel *mapSipAddressToContact (const QString &sip_address) const; ContactModel *mapSipAddressToContact (const QString &sip_address) const;
void handleAllHistoryEntriesRemoved (); void handleAllHistoryEntriesRemoved ();
ContactObserver *getContactObserver (const QString &sip_address);
private: private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
...@@ -33,8 +36,12 @@ private: ...@@ -33,8 +36,12 @@ private:
void fetchSipAddresses (); void fetchSipAddresses ();
void updateObservers (const QString &sip_address, ContactModel *contact);
QHash<QString, QVariantMap> m_sip_addresses; QHash<QString, QVariantMap> m_sip_addresses;
QList<const QVariantMap *> m_refs; QList<const QVariantMap *> m_refs;
QMultiHash<QString, ContactObserver *> m_observers;
}; };
#endif // SIP_ADDRESSES_MODEL_H_ #endif // SIP_ADDRESSES_MODEL_H_
...@@ -11,9 +11,7 @@ import Linphone.Styles 1.0 ...@@ -11,9 +11,7 @@ import Linphone.Styles 1.0
ColumnLayout { ColumnLayout {
property alias proxyModel: chat.model property alias proxyModel: chat.model
property var _contact: SipAddressesModel.mapSipAddressToContact( property var _contactObserver: SipAddressesModel.getContactObserver(proxyModel.sipAddress)
proxyModel.sipAddress
) || proxyModel.sipAddress
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
......
...@@ -20,8 +20,8 @@ RowLayout { ...@@ -20,8 +20,8 @@ RowLayout {
Avatar { Avatar {
anchors.centerIn: parent anchors.centerIn: parent
height: ChatStyle.entry.message.incoming.avatarSize height: ChatStyle.entry.message.incoming.avatarSize
image: _contact.avatar image: _contactObserver.contact ? _contactObserver.contact.avatar : ''
username: LinphoneUtils.getContactUsername(_contact) username: LinphoneUtils.getContactUsername(_contactObserver.contact || _contactObserver.sipAddress)
width: ChatStyle.entry.message.incoming.avatarSize width: ChatStyle.entry.message.incoming.avatarSize
} }
} }
......
...@@ -16,9 +16,7 @@ Rectangle { ...@@ -16,9 +16,7 @@ Rectangle {
property bool isVideoCall: false property bool isVideoCall: false
property string sipAddress property string sipAddress
property var _contact: SipAddressesModel.mapSipAddressToContact( property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress)
sipAddress
) || sipAddress
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -58,7 +56,7 @@ Rectangle { ...@@ -58,7 +56,7 @@ Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
horizontalTextAlignment: Text.AlignHCenter horizontalTextAlignment: Text.AlignHCenter
sipAddress: call.sipAddress sipAddress: call.sipAddress
username: LinphoneUtils.getContactUsername(_contact) username: LinphoneUtils.getContactUsername(_contactObserver.contact || call.sipAddress)
height: parent.height height: parent.height
width: parent.width - cameraActions.width - callQuality.width - 150 width: parent.width - cameraActions.width - callQuality.width - 150
...@@ -110,7 +108,7 @@ Rectangle { ...@@ -110,7 +108,7 @@ Rectangle {
} }
backgroundColor: StartingCallStyle.avatar.backgroundColor backgroundColor: StartingCallStyle.avatar.backgroundColor
image: _contact.vcard.avatar image: _contactObserver.contact ? _contactObserver.contact.vcard.avatar : ''
username: contactDescription.username username: contactDescription.username
height: _computeAvatarSize() height: _computeAvatarSize()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment