forked from blue/squawk
Now avatars are properly autogenerated, reduced vCard spam
This commit is contained in:
parent
93c5be412e
commit
0be2648849
@ -367,9 +367,13 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) {
|
|||||||
vh->handlePresenceOfMyAccountChange(p_presence);
|
vh->handlePresenceOfMyAccountChange(p_presence);
|
||||||
} else {
|
} else {
|
||||||
RosterItem* item = rh->getRosterItem(jid);
|
RosterItem* item = rh->getRosterItem(jid);
|
||||||
if (item != nullptr)
|
if (item != nullptr) {
|
||||||
|
if (item->isMuc()) //MUC presence is handled by inner muc events
|
||||||
|
return;
|
||||||
|
else
|
||||||
item->handlePresence(p_presence);
|
item->handlePresence(p_presence);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (p_presence.type()) {
|
switch (p_presence.type()) {
|
||||||
case QXmppPresence::Error:
|
case QXmppPresence::Error:
|
||||||
@ -377,9 +381,9 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) {
|
|||||||
break;
|
break;
|
||||||
case QXmppPresence::Available: {
|
case QXmppPresence::Available: {
|
||||||
QDateTime lastInteraction = p_presence.lastUserInteraction();
|
QDateTime lastInteraction = p_presence.lastUserInteraction();
|
||||||
if (!lastInteraction.isValid()) {
|
if (!lastInteraction.isValid())
|
||||||
lastInteraction = QDateTime::currentDateTimeUtc();
|
lastInteraction = QDateTime::currentDateTimeUtc();
|
||||||
}
|
|
||||||
emit addPresence(jid, resource, {
|
emit addPresence(jid, resource, {
|
||||||
{"lastActivity", lastInteraction},
|
{"lastActivity", lastInteraction},
|
||||||
{"availability", p_presence.availableStatusType()}, //TODO check and handle invisible
|
{"availability", p_presence.availableStatusType()}, //TODO check and handle invisible
|
||||||
@ -392,8 +396,7 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case QXmppPresence::Unavailable:
|
case QXmppPresence::Unavailable:
|
||||||
emit removePresence(jid, resource);
|
emit removePresence(jid, resource);
|
||||||
break;
|
break;
|
||||||
|
@ -132,9 +132,8 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) {
|
|||||||
|
|
||||||
if (resource.size() > 0) {
|
if (resource.size() > 0) {
|
||||||
QDateTime lastInteraction = pres.lastUserInteraction();
|
QDateTime lastInteraction = pres.lastUserInteraction();
|
||||||
if (!lastInteraction.isValid()) {
|
if (!lastInteraction.isValid())
|
||||||
lastInteraction = QDateTime::currentDateTimeUtc();
|
lastInteraction = QDateTime::currentDateTimeUtc();
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QVariant> cData = {
|
QMap<QString, QVariant> cData = {
|
||||||
{"lastActivity", lastInteraction},
|
{"lastActivity", lastInteraction},
|
||||||
@ -153,31 +152,39 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) {
|
|||||||
careAboutAvatar(hasAvatar, itr->second, cData, resource, p_name);
|
careAboutAvatar(hasAvatar, itr->second, cData, resource, p_name);
|
||||||
|
|
||||||
emit addParticipant(resource, cData);
|
emit addParticipant(resource, cData);
|
||||||
|
|
||||||
|
if (!hasAvatar) // because this way vCard is already requested, no need to handle possible avatar update
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handlePossibleAvatarUpdate(pres, resource, hasAvatar, itr->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::Conference::handlePossibleAvatarUpdate (
|
||||||
|
const QXmppPresence& pres,
|
||||||
|
const QString& resource,
|
||||||
|
bool hasAvatar,
|
||||||
|
const Archive::AvatarInfo& info
|
||||||
|
) {
|
||||||
switch (pres.vCardUpdateType()) {
|
switch (pres.vCardUpdateType()) {
|
||||||
case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo
|
case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo
|
||||||
break;
|
break;
|
||||||
case QXmppPresence::VCardUpdateNotReady: //let's say the photo didn't change here
|
case QXmppPresence::VCardUpdateNotReady: //let's say the photo didn't change here
|
||||||
break;
|
break;
|
||||||
case QXmppPresence::VCardUpdateNoPhoto: { //there is no photo, need to drop if any
|
case QXmppPresence::VCardUpdateNoPhoto: //there is no photo, need to drop if any
|
||||||
if (!hasAvatar || !itr->second.autogenerated) {
|
if (!hasAvatar || !info.autogenerated)
|
||||||
setAutoGeneratedAvatar(resource);
|
setAutoGeneratedAvatar(resource);
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load
|
|
||||||
if (hasAvatar) {
|
|
||||||
if (itr->second.autogenerated || itr->second.hash != pres.photoHash())
|
|
||||||
emit requestVCard(p_name);
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case QXmppPresence::VCardUpdateValidPhoto: //there is a photo, need to load
|
||||||
|
if (hasAvatar) {
|
||||||
|
if (info.autogenerated || info.hash != pres.photoHash())
|
||||||
|
emit requestVCard(pres.from());
|
||||||
} else {
|
} else {
|
||||||
emit requestVCard(p_name);
|
emit requestVCard(pres.from());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Core::Conference::onRoomParticipantChanged(const QString& p_name) {
|
void Core::Conference::onRoomParticipantChanged(const QString& p_name) {
|
||||||
QStringList comps = p_name.split("/");
|
QStringList comps = p_name.split("/");
|
||||||
@ -236,31 +243,9 @@ void Core::Conference::handlePresence(const QXmppPresence& pres) {
|
|||||||
if (comps.size() > 1)
|
if (comps.size() > 1)
|
||||||
resource = comps.back();
|
resource = comps.back();
|
||||||
|
|
||||||
switch (pres.vCardUpdateType()) {
|
|
||||||
case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo
|
|
||||||
break;
|
|
||||||
case QXmppPresence::VCardUpdateNotReady: //let's say the photo didn't change here
|
|
||||||
break;
|
|
||||||
case QXmppPresence::VCardUpdateNoPhoto: { //there is no photo, need to drop if any
|
|
||||||
Archive::AvatarInfo info;
|
Archive::AvatarInfo info;
|
||||||
bool hasAvatar = readAvatarInfo(info, resource);
|
bool hasAvatar = readAvatarInfo(info, resource);
|
||||||
if (!hasAvatar || !info.autogenerated) {
|
handlePossibleAvatarUpdate(pres, resource, hasAvatar, info);
|
||||||
setAutoGeneratedAvatar(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load
|
|
||||||
Archive::AvatarInfo info;
|
|
||||||
bool hasAvatar = readAvatarInfo(info, resource);
|
|
||||||
if (hasAvatar) {
|
|
||||||
if (info.autogenerated || info.hash != pres.photoHash())
|
|
||||||
emit requestVCard(id);
|
|
||||||
} else {
|
|
||||||
emit requestVCard(id);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::Conference::setAutoGeneratedAvatar(const QString& resource) {
|
bool Core::Conference::setAutoGeneratedAvatar(const QString& resource) {
|
||||||
@ -272,6 +257,7 @@ bool Core::Conference::setAutoGeneratedAvatar(const QString& resource) {
|
|||||||
exParticipants.insert(std::make_pair(resource, newInfo));
|
exParticipants.insert(std::make_pair(resource, newInfo));
|
||||||
else
|
else
|
||||||
itr->second = newInfo;
|
itr->second = newInfo;
|
||||||
|
|
||||||
emit changeParticipant(resource, {
|
emit changeParticipant(resource, {
|
||||||
{"avatarState", static_cast<uint>(Shared::Avatar::autocreated)},
|
{"avatarState", static_cast<uint>(Shared::Avatar::autocreated)},
|
||||||
{"avatarPath", avatarPath(resource) + "." + newInfo.type}
|
{"avatarPath", avatarPath(resource) + "." + newInfo.type}
|
||||||
@ -313,18 +299,18 @@ bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& in
|
|||||||
|
|
||||||
void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QString &resource, Shared::VCard& out) {
|
void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QString &resource, Shared::VCard& out) {
|
||||||
RosterItem::handleResponseVCard(card, resource, out);
|
RosterItem::handleResponseVCard(card, resource, out);
|
||||||
if (resource.size() > 0) {
|
if (resource.size() > 0)
|
||||||
emit changeParticipant(resource, {
|
emit changeParticipant(resource, {
|
||||||
{"avatarState", static_cast<uint>(out.getAvatarType())},
|
{"avatarState", static_cast<uint>(out.getAvatarType())},
|
||||||
{"avatarPath", out.getAvatarPath()}
|
{"avatarPath", out.getAvatarPath()}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QVariant> Core::Conference::getAllAvatars() const {
|
QMap<QString, QVariant> Core::Conference::getAllAvatars() const {
|
||||||
QMap<QString, QVariant> result;
|
QMap<QString, QVariant> result;
|
||||||
for (const std::pair<const QString, Archive::AvatarInfo>& pair : exParticipants)
|
for (const std::pair<const QString, Archive::AvatarInfo>& pair : exParticipants)
|
||||||
result.insert(pair.first, avatarPath(pair.first) + "." + pair.second.type);
|
result.insert(pair.first, avatarPath(pair.first) + "." + pair.second.type);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CORE_CONFERENCE_H
|
#pragma once
|
||||||
#define CORE_CONFERENCE_H
|
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
@ -29,14 +28,8 @@
|
|||||||
#include <shared/global.h>
|
#include <shared/global.h>
|
||||||
#include <shared/clientid.h>
|
#include <shared/clientid.h>
|
||||||
|
|
||||||
namespace Core
|
namespace Core {
|
||||||
{
|
class Conference : public RosterItem {
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo write docs
|
|
||||||
*/
|
|
||||||
class Conference : public RosterItem
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Conference(const QString& p_jid, const QString& p_account, bool p_autoJoin, const QString& p_name, const QString& p_nick, QXmppMucRoom* p_room);
|
Conference(const QString& p_jid, const QString& p_account, bool p_autoJoin, const QString& p_name, const QString& p_nick, QXmppMucRoom* p_room);
|
||||||
@ -69,6 +62,14 @@ signals:
|
|||||||
protected:
|
protected:
|
||||||
bool setAvatar(const QByteArray &data, Archive::AvatarInfo& info, const QString &resource = "") override;
|
bool setAvatar(const QByteArray &data, Archive::AvatarInfo& info, const QString &resource = "") override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handlePossibleAvatarUpdate(
|
||||||
|
const QXmppPresence& pres,
|
||||||
|
const QString& resource,
|
||||||
|
bool hasAvatar,
|
||||||
|
const Archive::AvatarInfo& info
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString nick;
|
QString nick;
|
||||||
QXmppMucRoom* room;
|
QXmppMucRoom* room;
|
||||||
@ -91,5 +92,3 @@ private slots:
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CORE_CONFERENCE_H
|
|
||||||
|
@ -73,18 +73,17 @@ void Core::Contact::handlePresence(const QXmppPresence& pres) {
|
|||||||
case QXmppPresence::VCardUpdateNoPhoto: { //there is no photo, need to drop if any
|
case QXmppPresence::VCardUpdateNoPhoto: { //there is no photo, need to drop if any
|
||||||
Archive::AvatarInfo info;
|
Archive::AvatarInfo info;
|
||||||
bool hasAvatar = readAvatarInfo(info);
|
bool hasAvatar = readAvatarInfo(info);
|
||||||
if (!hasAvatar || !info.autogenerated) {
|
if (!hasAvatar || !info.autogenerated)
|
||||||
setAutoGeneratedAvatar();
|
setAutoGeneratedAvatar();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load
|
case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load
|
||||||
Archive::AvatarInfo info;
|
Archive::AvatarInfo info;
|
||||||
bool hasAvatar = readAvatarInfo(info);
|
bool hasAvatar = readAvatarInfo(info);
|
||||||
if (hasAvatar) {
|
if (hasAvatar) {
|
||||||
if (info.autogenerated || info.hash != pres.photoHash()) {
|
if (info.autogenerated || info.hash != pres.photoHash())
|
||||||
emit requestVCard(jid);
|
emit requestVCard(jid);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
emit requestVCard(jid);
|
emit requestVCard(jid);
|
||||||
}
|
}
|
||||||
|
@ -98,13 +98,13 @@ void Core::RosterHandler::addedAccount(const QString& jid) {
|
|||||||
contact->setName(re.name());
|
contact->setName(re.name());
|
||||||
|
|
||||||
if (newContact) {
|
if (newContact) {
|
||||||
|
handleNewContact(contact);
|
||||||
QMap<QString, QVariant> cData = contact->getInfo();
|
QMap<QString, QVariant> cData = contact->getInfo();
|
||||||
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0)
|
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0)
|
||||||
cData.insert("trust", QVariant::fromValue(acc->th->getSummary(jid)));
|
cData.insert("trust", QVariant::fromValue(acc->th->getSummary(jid)));
|
||||||
#endif
|
#endif
|
||||||
int grCount = 0;
|
int grCount = 0;
|
||||||
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
|
for (const QString& groupName : gr) {
|
||||||
const QString& groupName = *itr;
|
|
||||||
addToGroup(jid, groupName);
|
addToGroup(jid, groupName);
|
||||||
emit acc->addContact(jid, groupName, cData);
|
emit acc->addContact(jid, groupName, cData);
|
||||||
grCount++;
|
grCount++;
|
||||||
@ -117,7 +117,6 @@ void Core::RosterHandler::addedAccount(const QString& jid) {
|
|||||||
acc->dm->requestInfo(jid);
|
acc->dm->requestInfo(jid);
|
||||||
//acc->dm->requestItems(jid);
|
//acc->dm->requestItems(jid);
|
||||||
}
|
}
|
||||||
handleNewContact(contact);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +494,9 @@ void Core::RosterHandler::removeContactFromGroupRequest(const QString& jid, cons
|
|||||||
if (itr == contacts.end()) {
|
if (itr == contacts.end()) {
|
||||||
qDebug() << "An attempt to remove non existing contact" << lcJid << "of account"
|
qDebug() << "An attempt to remove non existing contact" << lcJid << "of account"
|
||||||
<< acc->name << "from the group" << groupName << ", skipping";
|
<< acc->name << "from the group" << groupName << ", skipping";
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QXmppRosterIq::Item item = acc->rm->getRosterEntry(lcJid);
|
QXmppRosterIq::Item item = acc->rm->getRosterEntry(lcJid);
|
||||||
QSet<QString> groups = item.groups();
|
QSet<QString> groups = item.groups();
|
||||||
QSet<QString>::const_iterator gItr = groups.find(groupName);
|
QSet<QString>::const_iterator gItr = groups.find(groupName);
|
||||||
@ -512,7 +513,6 @@ void Core::RosterHandler::removeContactFromGroupRequest(const QString& jid, cons
|
|||||||
<< acc->name << "from the group" << groupName << "but it's not in that group, skipping";
|
<< acc->name << "from the group" << groupName << "but it's not in that group, skipping";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Core::RosterHandler::onContactAvatarChanged(Shared::Avatar type, const QString& path) {
|
void Core::RosterHandler::onContactAvatarChanged(Shared::Avatar type, const QString& path) {
|
||||||
RosterItem* item = static_cast<RosterItem*>(sender());
|
RosterItem* item = static_cast<RosterItem*>(sender());
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CORE_ROSTERITEM_H
|
#pragma once
|
||||||
#define CORE_ROSTERITEM_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@ -130,5 +129,3 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CORE_ROSTERITEM_H
|
|
||||||
|
2
external/lmdbal
vendored
2
external/lmdbal
vendored
@ -1 +1 @@
|
|||||||
Subproject commit c83369f34761e7a053d62312bd07fe5b3db3a519
|
Subproject commit 79240aa5354e9fa9d09d3b12ea1077a81bb90809
|
2
external/qxmpp
vendored
2
external/qxmpp
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 8dda3c9921c34b9e33883b0d140e8de12edc0736
|
Subproject commit 0cd7379bd78aa01af7e84f2fad6269ef0c0ba49c
|
@ -650,10 +650,10 @@ void Models::Roster::onChildRemoved() {
|
|||||||
void Models::Roster::addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data) {
|
void Models::Roster::addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data) {
|
||||||
ElId contactId(account, jid);
|
ElId contactId(account, jid);
|
||||||
std::map<ElId, Contact*>::iterator itr = contacts.find(contactId);
|
std::map<ElId, Contact*>::iterator itr = contacts.find(contactId);
|
||||||
if (itr != contacts.end()) {
|
if (itr != contacts.end())
|
||||||
itr->second->addPresence(name, data);
|
itr->second->addPresence(name, data);
|
||||||
}
|
else
|
||||||
|
qDebug() << "Received a presence" << jid + "/" + name << "don't know what to do with it";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::Roster::removePresence(const QString& account, const QString& jid, const QString& name) {
|
void Models::Roster::removePresence(const QString& account, const QString& jid, const QString& name) {
|
||||||
|
Loading…
Reference in New Issue
Block a user