forked from blue/squawk
receiving avatars, generating missing avatars, storing state of avatars, global color palette
This commit is contained in:
parent
c678a790e5
commit
64e33b6139
8 changed files with 375 additions and 38 deletions
159
core/account.cpp
159
core/account.cpp
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue