1
0
Fork 0
forked from blue/squawk

receiving avatars, generating missing avatars, storing state of avatars, global color palette

This commit is contained in:
Blue 2019-10-15 22:25:40 +03:00
parent c678a790e5
commit 64e33b6139
8 changed files with 375 additions and 38 deletions

View file

@ -48,37 +48,39 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
config.setPassword(p_password);
config.setAutoAcceptSubscriptions(true);
QObject::connect(&client, SIGNAL(connected()), this, SLOT(onClientConnected()));
QObject::connect(&client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
QObject::connect(&client, SIGNAL(presenceReceived(const QXmppPresence&)), this, SLOT(onPresenceReceived(const QXmppPresence&)));
QObject::connect(&client, SIGNAL(messageReceived(const QXmppMessage&)), this, SLOT(onMessageReceived(const QXmppMessage&)));
QObject::connect(&client, SIGNAL(error(QXmppClient::Error)), this, SLOT(onClientError(QXmppClient::Error)));
QObject::connect(&client, &QXmppClient::connected, this, &Account::onClientConnected);
QObject::connect(&client, &QXmppClient::disconnected, this, &Account::onClientDisconnected);
QObject::connect(&client, &QXmppClient::presenceReceived, this, &Account::onPresenceReceived);
QObject::connect(&client, &QXmppClient::messageReceived, this, &Account::onMessageReceived);
QObject::connect(&client, &QXmppClient::error, this, &Account::onClientError);
QXmppRosterManager& rm = client.rosterManager();
QObject::connect(&rm, SIGNAL(rosterReceived()), this, SLOT(onRosterReceived()));
QObject::connect(&rm, SIGNAL(itemAdded(const QString&)), this, SLOT(onRosterItemAdded(const QString&)));
QObject::connect(&rm, SIGNAL(itemRemoved(const QString&)), this, SLOT(onRosterItemRemoved(const QString&)));
QObject::connect(&rm, SIGNAL(itemChanged(const QString&)), this, SLOT(onRosterItemChanged(const QString&)));
//QObject::connect(&rm, SIGNAL(presenceChanged(const QString&, const QString&)), this, SLOT(onRosterPresenceChanged(const QString&, const QString&)));
QObject::connect(&rm, &QXmppRosterManager::rosterReceived, this, &Account::onRosterReceived);
QObject::connect(&rm, &QXmppRosterManager::itemAdded, this, &Account::onRosterItemAdded);
QObject::connect(&rm, &QXmppRosterManager::itemRemoved, this, &Account::onRosterItemRemoved);
QObject::connect(&rm, &QXmppRosterManager::itemChanged, this, &Account::onRosterItemChanged);
//QObject::connect(&rm, &QXmppRosterManager::presenceChanged, this, &Account::onRosterPresenceChanged);
client.addExtension(cm);
QObject::connect(cm, SIGNAL(messageReceived(const QXmppMessage&)), this, SLOT(onCarbonMessageReceived(const QXmppMessage&)));
QObject::connect(cm, SIGNAL(messageSent(const QXmppMessage&)), this, SLOT(onCarbonMessageSent(const QXmppMessage&)));
QObject::connect(cm, &QXmppCarbonManager::messageReceived, this, &Account::onCarbonMessageReceived);
QObject::connect(cm, &QXmppCarbonManager::messageSent, this, &Account::onCarbonMessageSent);
client.addExtension(am);
QObject::connect(am, SIGNAL(logMessage(QXmppLogger::MessageType, const QString&)), this, SLOT(onMamLog(QXmppLogger::MessageType, const QString)));
QObject::connect(am, SIGNAL(archivedMessageReceived(const QString&, const QXmppMessage&)), this, SLOT(onMamMessageReceived(const QString&, const QXmppMessage&)));
QObject::connect(am, SIGNAL(resultsRecieved(const QString&, const QXmppResultSetReply&, bool)),
this, SLOT(onMamResultsReceived(const QString&, const QXmppResultSetReply&, bool)));
QObject::connect(am, &QXmppMamManager::logMessage, this, &Account::onMamLog);
QObject::connect(am, &QXmppMamManager::archivedMessageReceived, this, &Account::onMamMessageReceived);
QObject::connect(am, &QXmppMamManager::resultsRecieved, this, &Account::onMamResultsReceived);
client.addExtension(mm);
QObject::connect(mm, SIGNAL(roomAdded(QXmppMucRoom*)), this, SLOT(onMucRoomAdded(QXmppMucRoom*)));
QObject::connect(mm, &QXmppMucManager::roomAdded, this, &Account::onMucRoomAdded);
client.addExtension(bm);
QObject::connect(bm, SIGNAL(bookmarksReceived(const QXmppBookmarkSet&)), this, SLOT(bookmarksReceived(const QXmppBookmarkSet&)));
QObject::connect(bm, &QXmppBookmarkManager::bookmarksReceived, this, &Account::bookmarksReceived);
QXmppVCardManager& vm = client.vCardManager();
QObject::connect(&vm, &QXmppVCardManager::vCardReceived, this, &Account::onVCardReceived);
}
Account::~Account()
@ -279,6 +281,19 @@ void Core::Account::addedAccount(const QString& jid)
{"name", re.name()},
{"state", state}
});
if (contact->hasAvatar()) {
if (contact->isAvatarAutoGenerated()) {
cData.insert("avatarType", static_cast<uint>(Shared::Avatar::valid));
} else {
cData.insert("avatarType", static_cast<uint>(Shared::Avatar::autocreated));
}
cData.insert("avatarPath", contact->avatarPath());
} else {
cData.insert("avatarType", static_cast<uint>(Shared::Avatar::empty));
client.vCardManager().requestVCard(jid);
pendingVCardRequests.insert(jid);
}
int grCount = 0;
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
const QString& groupName = *itr;
@ -296,36 +311,32 @@ void Core::Account::addedAccount(const QString& jid)
void Core::Account::handleNewRosterItem(Core::RosterItem* contact)
{
QObject::connect(contact, SIGNAL(needHistory(const QString&, const QString&, const QDateTime&)), this, SLOT(onContactNeedHistory(const QString&, const QString&, const QDateTime&)));
QObject::connect(contact, SIGNAL(historyResponse(const std::list<Shared::Message>&)), this, SLOT(onContactHistoryResponse(const std::list<Shared::Message>&)));
QObject::connect(contact, SIGNAL(nameChanged(const QString&)), this, SLOT(onContactNameChanged(const QString&)));
QObject::connect(contact, &RosterItem::needHistory, this, &Account::onContactNeedHistory);
QObject::connect(contact, &RosterItem::historyResponse, this, &Account::onContactHistoryResponse);
QObject::connect(contact, &RosterItem::nameChanged, this, &Account::onContactNameChanged);
QObject::connect(contact, &RosterItem::avatarChanged, this, &Account::onContactAvatarChanged);
}
void Core::Account::handleNewContact(Core::Contact* contact)
{
handleNewRosterItem(contact);
QObject::connect(contact, SIGNAL(groupAdded(const QString&)), this, SLOT(onContactGroupAdded(const QString&)));
QObject::connect(contact, SIGNAL(groupRemoved(const QString&)), this, SLOT(onContactGroupRemoved(const QString&)));
QObject::connect(contact, SIGNAL(subscriptionStateChanged(Shared::SubscriptionState)),
this, SLOT(onContactSubscriptionStateChanged(Shared::SubscriptionState)));
QObject::connect(contact, &Contact::groupAdded, this, &Account::onContactGroupAdded);
QObject::connect(contact, &Contact::groupRemoved, this, &Account::onContactGroupRemoved);
QObject::connect(contact, &Contact::subscriptionStateChanged, this, &Account::onContactSubscriptionStateChanged);
}
void Core::Account::handleNewConference(Core::Conference* contact)
{
handleNewRosterItem(contact);
QObject::connect(contact, SIGNAL(nickChanged(const QString&)), this, SLOT(onMucNickNameChanged(const QString&)));
QObject::connect(contact, SIGNAL(subjectChanged(const QString&)), this, SLOT(onMucSubjectChanged(const QString&)));
QObject::connect(contact, SIGNAL(joinedChanged(bool)), this, SLOT(onMucJoinedChanged(bool)));
QObject::connect(contact, SIGNAL(autoJoinChanged(bool)), this, SLOT(onMucAutoJoinChanged(bool)));
QObject::connect(contact, SIGNAL(addParticipant(const QString&, const QMap<QString, QVariant>&)),
this, SLOT(onMucAddParticipant(const QString&, const QMap<QString, QVariant>&)));
QObject::connect(contact, SIGNAL(changeParticipant(const QString&, const QMap<QString, QVariant>&)),
this, SLOT(onMucChangeParticipant(const QString&, const QMap<QString, QVariant>&)));
QObject::connect(contact, SIGNAL(removeParticipant(const QString&)), this, SLOT(onMucRemoveParticipant(const QString&)));
QObject::connect(contact, &Conference::nickChanged, this, &Account::onMucNickNameChanged);
QObject::connect(contact, &Conference::subjectChanged, this, &Account::onMucSubjectChanged);
QObject::connect(contact, &Conference::joinedChanged, this, &Account::onMucJoinedChanged);
QObject::connect(contact, &Conference::autoJoinChanged, this, &Account::onMucAutoJoinChanged);
QObject::connect(contact, &Conference::addParticipant, this, &Account::onMucAddParticipant);
QObject::connect(contact, &Conference::changeParticipant, this, &Account::onMucChangeParticipant);
QObject::connect(contact, &Conference::removeParticipant, this, &Account::onMucRemoveParticipant);
}
void Core::Account::onPresenceReceived(const QXmppPresence& presence)
{
QString id = presence.from();
@ -341,11 +352,45 @@ void Core::Account::onPresenceReceived(const QXmppPresence& presence)
} else {
qDebug() << "Received a presence for another resource of my " << name << " account, skipping";
}
} else {
if (pendingVCardRequests.find(jid) == pendingVCardRequests.end()) {
std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
if (itr != contacts.end()) {
Contact* cnt = itr->second;
switch (presence.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
if (!cnt->hasAvatar() || (cnt->hasAvatar() && !cnt->isAvatarAutoGenerated())) {
cnt->setAutoGeneratedAvatar();
}
break;
case QXmppPresence::VCardUpdateValidPhoto: //there is a photo, need to load
if (cnt->hasAvatar()) {
if (cnt->isAvatarAutoGenerated()) {
client.vCardManager().requestVCard(jid);
pendingVCardRequests.insert(jid);
} else {
if (cnt->avatarHash() != presence.photoHash()) {
client.vCardManager().requestVCard(jid);
pendingVCardRequests.insert(jid);
}
}
} else {
client.vCardManager().requestVCard(jid);
pendingVCardRequests.insert(jid);
}
break;
}
}
}
}
switch (presence.type()) {
case QXmppPresence::Error:
qDebug() << "An error reported by presence from " << id;
qDebug() << "An error reported by presence from" << id << presence.error().text();
break;
case QXmppPresence::Available:{
QDateTime lastInteraction = presence.lastUserInteraction();
@ -1211,3 +1256,43 @@ void Core::Account::renameContactRequest(const QString& jid, const QString& newN
rm.renameItem(jid, newName);
}
}
void Core::Account::onVCardReceived(const QXmppVCardIq& card)
{
QString jid = card.from();
pendingVCardRequests.erase(jid);
RosterItem* item = 0;
std::map<QString, Contact*>::const_iterator contItr = contacts.find(jid);
if (contItr == contacts.end()) {
std::map<QString, Conference*>::const_iterator confItr = conferences.find(jid);
if (confItr == conferences.end()) {
qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping";
return;
} else {
item = confItr->second;
}
} else {
item = contItr->second;
}
QByteArray ava = card.photo();
if (ava.size() > 0) {
item->setAvatar(ava);
} else {
item->setAutoGeneratedAvatar();
}
}
void Core::Account::onContactAvatarChanged(Shared::Avatar type, const QString& path)
{
RosterItem* item = static_cast<RosterItem*>(sender());
QMap<QString, QVariant> cData({
{"avatarType", static_cast<uint>(type)}
});
if (type != Shared::Avatar::empty) {
cData.insert("avatarPath", path);
}
emit changeContact(item->jid, cData);
}