Commit a3f0062d authored by Ronan Abhamon's avatar Ronan Abhamon

feat(src/components/sip-addresses/SipAddressesModel): connect to contacts changes

parent b8780f79
......@@ -65,6 +65,8 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren
ContactModel *contact = m_list.takeAt(row);
m_linphone_friends->removeFriend(contact->m_linphone_friend);
emit contactRemoved(contact);
contact->deleteLater();
}
......@@ -96,6 +98,8 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcard) {
m_list << contact;
endInsertRows();
emit contactAdded(contact);
return contact;
}
......
......@@ -29,6 +29,10 @@ public slots:
ContactModel *addContact (VcardModel *vcard);
void removeContact (ContactModel *contact);
signals:
void contactAdded (ContactModel *contact);
void contactRemoved (const ContactModel *contact);
private:
QList<ContactModel *> m_list;
std::shared_ptr<linphone::FriendList> m_linphone_friends;
......
#include <QDateTime>
#include <QSet>
#include <QtDebug>
#include "../../utils.hpp"
#include "../contacts/ContactsListModel.hpp"
#include "../core/CoreManager.hpp"
#include "SipAddressesModel.hpp"
......@@ -10,6 +10,101 @@
// =============================================================================
SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(parent) {
fetchSipAddresses();
QObject::connect(
CoreManager::getInstance()->getContactsListModel(), &ContactsListModel::contactAdded,
this, &SipAddressesModel::updateFromContact
);
QObject::connect(
CoreManager::getInstance()->getContactsListModel(), &ContactsListModel::contactRemoved,
this, [this](const ContactModel *contact) {
for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) {
auto it = m_sip_addresses.find(sip_address.toString());
if (it == m_sip_addresses.end()) {
qWarning() << QStringLiteral("Unable to remove contact from sip address: `%1`.").arg(
sip_address.toString()
);
continue;
}
if (it->remove("contact") != 0) {
int row = static_cast<int>(distance(m_sip_addresses.begin(), it));
emit dataChanged(index(row, 0), index(row, 0));
}
}
}
);
// TODO: handle data changed from contact
}
// -----------------------------------------------------------------------------
int SipAddressesModel::rowCount (const QModelIndex &) const {
return m_refs.count();
}
QHash<int, QByteArray> SipAddressesModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$sipAddress";
return roles;
}
QVariant SipAddressesModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= m_refs.count())
return QVariant();
if (role == Qt::DisplayRole)
return QVariant::fromValue(*m_refs[row]);
return QVariant();
}
// -----------------------------------------------------------------------------
ContactModel *SipAddressesModel::mapSipAddressToContact (const QString &sip_address) const {
auto it = m_sip_addresses.find(sip_address);
if (it == m_sip_addresses.end())
return nullptr;
return it->value("contact").value<ContactModel *>();
}
// -----------------------------------------------------------------------------
void SipAddressesModel::updateFromContact (ContactModel *contact) {
for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) {
const QString &sip_address_str = sip_address.toString();
auto it = m_sip_addresses.find(sip_address_str);
// New sip address from contact = new entry.
if (it == m_sip_addresses.end()) {
QVariantMap map;
map["sipAddress"] = sip_address;
map["contact"] = QVariant::fromValue(contact);
m_sip_addresses[sip_address_str] = map;
m_refs << &m_sip_addresses[sip_address_str];
int row = m_refs.count() - 1;
emit dataChanged(index(row, 0), index(row, 0));
continue;
}
// Sip address exists, update contact.
(*it)["contact"] = QVariant::fromValue(contact);
int row = m_refs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
}
}
void SipAddressesModel::fetchSipAddresses () {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
// Get sip addresses from chatrooms.
......@@ -48,55 +143,10 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
m_sip_addresses[sip_address] = map;
}
// Get sip addresses from contacts.
for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list) {
for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) {
auto it = m_sip_addresses.find(sip_address.toString());
if (it == m_sip_addresses.end()) {
QVariantMap map;
map["sipAddress"] = sip_address;
map["contact"] = QVariant::fromValue(contact);
m_sip_addresses[sip_address.toString()] = map;
} else
(*it)["contact"] = QVariant::fromValue(contact);
}
}
for (const auto &map : m_sip_addresses)
m_refs << &map;
}
// -----------------------------------------------------------------------------
int SipAddressesModel::rowCount (const QModelIndex &) const {
return m_refs.count();
}
QHash<int, QByteArray> SipAddressesModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$sipAddress";
return roles;
}
QVariant SipAddressesModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= m_refs.count())
return QVariant();
if (role == Qt::DisplayRole)
return QVariant::fromValue(*m_refs[row]);
return QVariant();
}
// ------------------------------------------------------------------------------
ContactModel *SipAddressesModel::mapSipAddressToContact (const QString &sip_address) const {
auto it = m_sip_addresses.find(sip_address);
if (it == m_sip_addresses.end())
return nullptr;
return it->value("contact").value<ContactModel *>();
// Get sip addresses from contacts.
for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list)
updateFromContact(contact);
}
......@@ -23,6 +23,9 @@ public slots:
ContactModel *mapSipAddressToContact (const QString &sip_address) const;
private:
void updateFromContact (ContactModel *contact);
void fetchSipAddresses ();
QHash<QString, QVariantMap> m_sip_addresses;
QList<const QVariantMap *> m_refs;
};
......
......@@ -5,6 +5,7 @@ import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import Linphone.Styles 1.0
import Utils 1.0
// =============================================================================
......@@ -16,11 +17,20 @@ Rectangle {
property alias actions: actionBar.data
property alias sipAddressColor: description.sipAddressColor
property alias usernameColor: description.usernameColor
property string sipAddress
property var _contact: SipAddressesModel.mapSipAddressToContact(sipAddress)
// Can be a SipAddress object of SipAddressesModel or just a string.
property var sipAddress
property var _contact: Utils.isObject(sipAddress)
? sipAddress.contact
: SipAddressesModel.mapSipAddressToContact(sipAddress)
// ---------------------------------------------------------------------------
function _getSipAddress () {
return item.sipAddress.sipAddress || item.sipAddress
}
color: 'transparent' // No color by default.
height: ContactStyle.height
......@@ -39,7 +49,7 @@ Rectangle {
Layout.preferredWidth: ContactStyle.contentHeight
image: _contact && _contact.vcard.avatar
presenceLevel: _contact ? _contact.presenceLevel : Presence.White
username: LinphoneUtils.getContactUsername(_contact || sipAddress)
username: LinphoneUtils.getContactUsername(_contact || _getSipAddress())
}
ContactDescription {
......@@ -47,7 +57,7 @@ Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
sipAddress: item.sipAddress
sipAddress: _getSipAddress()
username: avatar.username
}
......
......@@ -85,17 +85,6 @@ ColumnLayout {
currentIndex: -1
delegate: Item {
property var contact: {
Utils.assert(
!Utils.isArray($timelineEntry.sipAddress),
'Conferences are not supported at this moment.'
)
return SipAddressesModel.mapSipAddressToContact(
$timelineEntry.sipAddress
) || $timelineEntry.sipAddress
}
height: TimelineStyle.contact.height
width: parent ? parent.width : 0
......@@ -108,7 +97,7 @@ ColumnLayout {
? TimelineStyle.contact.backgroundColor.a
: TimelineStyle.contact.backgroundColor.b
)
sipAddress: $timelineEntry.sipAddress
sipAddress: $timelineEntry
sipAddressColor: view.currentIndex === index
? TimelineStyle.contact.sipAddress.color.selected
: TimelineStyle.contact.sipAddress.color.normal
......
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