diff options
-rw-r--r-- | Swift/Controllers/MainController.cpp | 51 | ||||
-rw-r--r-- | Swift/Controllers/MainController.h | 6 | ||||
-rw-r--r-- | Swiften/Avatars/AvatarManager.cpp | 6 | ||||
-rw-r--r-- | Swiften/Avatars/AvatarManager.h | 1 | ||||
-rw-r--r-- | Swiften/Elements/VCardUpdate.h | 2 |
5 files changed, 60 insertions, 6 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 93b7c2a..6f1e02b 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -24,6 +24,7 @@ #include "Swiften/Base/String.h" #include "Swiften/Client/Client.h" #include "Swiften/Elements/Presence.h" +#include "Swiften/Elements/VCardUpdate.h" #include "Swiften/Roster/XMPPRoster.h" #include "Swiften/Queries/Responders/SoftwareVersionResponder.h" #include "Swiften/Roster/TreeWidgetFactory.h" @@ -32,8 +33,20 @@ #include "Swiften/Queries/Responders/DiscoInfoResponder.h" #include "Swiften/Disco/CapsInfoGenerator.h" #include "Swiften/Queries/Requests/GetDiscoInfoRequest.h" +#include "Swiften/Queries/Requests/GetVCardRequest.h" #include "Swiften/Avatars/AvatarFileStorage.h" #include "Swiften/Avatars/AvatarManager.h" +#include "Swiften/StringCodecs/SHA1.h" + +namespace { + void printIncomingData(const Swift::String& data) { + std::cout << "<- " << data << std::endl; + } + + void printOutgoingData(const Swift::String& data) { + std::cout << "-> " << data << std::endl; + } +} namespace Swift { @@ -82,6 +95,8 @@ void MainController::handleConnected() { delete presenceOracle_; presenceOracle_ = new PresenceOracle(client_); + lastSentPresence_ = boost::shared_ptr<Presence>(); + client_->onPresenceReceived.connect(boost::bind(&MainController::handleIncomingPresence, this, _1)); boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster()); @@ -118,11 +133,15 @@ void MainController::handleConnected() { boost::shared_ptr<GetDiscoInfoRequest> discoInfoRequest(new GetDiscoInfoRequest(JID(), client_)); discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2)); discoInfoRequest->send(); + + boost::shared_ptr<GetVCardRequest> vCardRequest(new GetVCardRequest(JID(), client_)); + vCardRequest->onResponse.connect(boost::bind(&MainController::handleOwnVCardReceived, this, _1, _2)); + vCardRequest->send(); //Send presence last to catch all the incoming presences. boost::shared_ptr<Presence> initialPresence(new Presence()); initialPresence->addPayload(capsInfo_); - client_->sendPresence(initialPresence); + sendPresence(initialPresence); } void MainController::handleEventQueueLengthChange(int count) { @@ -132,12 +151,22 @@ void MainController::handleEventQueueLengthChange(int count) { void MainController::handleChangeStatusRequest(StatusShow::Type show, const String &statusText) { boost::shared_ptr<Presence> presence(new Presence()); presence->addPayload(capsInfo_); - presence->setShow(show); - presence->setStatus(statusText); - // FIXME: This is wrong. None doesn't mean unavailable if (show == StatusShow::None) { + // FIXME: This is wrong. None doesn't mean unavailable presence->setType(Presence::Unavailable); } + else { + presence->setShow(show); + } + presence->setStatus(statusText); + sendPresence(presence); +} + +void MainController::sendPresence(boost::shared_ptr<Presence> presence) { + if (!vCardPhotoHash_.isEmpty()) { + presence->addPayload(boost::shared_ptr<VCardUpdate>(new VCardUpdate(vCardPhotoHash_))); + } + lastSentPresence_ = presence; client_->sendPresence(presence); if (presence->getType() == Presence::Unavailable) { logout(); @@ -156,7 +185,10 @@ void MainController::handleLoginRequest(const String &username, const String &pa settings_->storeString("pass", remember ? password : ""); delete client_; - client_ = new Swift::Client(JID(username), password); + jid_ = JID(username); + client_ = new Swift::Client(jid_, password); + //client_->onDataRead.connect(&printIncomingData); + //client_->onDataWritten.connect(&printOutgoingData); if (!certificateFile.isEmpty()) { client_->setCertificate(certificateFile); } @@ -275,5 +307,14 @@ bool MainController::isMUC(const JID& jid) const { return mucControllers_.find(jid.toBare()) != mucControllers_.end(); } +void MainController::handleOwnVCardReceived(boost::shared_ptr<VCard> vCard, const boost::optional<Error>& error) { + if (!error && !vCard->getPhoto().isEmpty()) { + vCardPhotoHash_ = SHA1::getHexHash(vCard->getPhoto()); + if (lastSentPresence_) { + sendPresence(lastSentPresence_); + } + avatarManager_->setAvatar(jid_, vCard->getPhoto()); + } +} } diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index 650afd1..2b7c8b0 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -8,6 +8,7 @@ #include "Swiften/Base/String.h" #include "Swiften/Client/ClientError.h" #include "Swiften/JID/JID.h" +#include "Swiften/Elements/VCard.h" #include "Swiften/Elements/DiscoInfo.h" #include "Swiften/Elements/Error.h" #include "Swiften/Elements/Presence.h" @@ -58,7 +59,9 @@ namespace Swift { void handleError(const ClientError& error); void handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>, const boost::optional<Error>&); void handleEventQueueLengthChange(int count); + void handleOwnVCardReceived(boost::shared_ptr<VCard> vCard, const boost::optional<Error>& error); ChatController* getChatController(const JID &contact); + void sendPresence(boost::shared_ptr<Presence> presence); void logout(); virtual bool isMUC(const JID& muc) const; @@ -84,9 +87,12 @@ namespace Swift { std::map<JID, MUCController*> mucControllers_; std::map<JID, ChatController*> chatControllers_; boost::shared_ptr<DiscoInfo> serverDiscoInfo_; + JID jid_; PresenceOracle* presenceOracle_; SystemTrayController* systemTrayController_; AvatarManager* avatarManager_; + boost::shared_ptr<Presence> lastSentPresence_; + String vCardPhotoHash_; }; } #endif diff --git a/Swiften/Avatars/AvatarManager.cpp b/Swiften/Avatars/AvatarManager.cpp index c15d002..6a1efc6 100644 --- a/Swiften/Avatars/AvatarManager.cpp +++ b/Swiften/Avatars/AvatarManager.cpp @@ -49,6 +49,12 @@ void AvatarManager::handleVCardReceived(const JID& from, const String& promisedH setAvatarHash(from, realHash); } +void AvatarManager::setAvatar(const JID& jid, const ByteArray& avatar) { + String hash = SHA1::getHexHash(avatar); + avatarStorage_->addAvatar(hash, avatar); + setAvatarHash(getAvatarJID(jid), hash); +} + void AvatarManager::setAvatarHash(const JID& from, const String& hash) { avatarHashes_[from] = hash; onAvatarChanged(from, hash); diff --git a/Swiften/Avatars/AvatarManager.h b/Swiften/Avatars/AvatarManager.h index 13c6cb7..984ce19 100644 --- a/Swiften/Avatars/AvatarManager.h +++ b/Swiften/Avatars/AvatarManager.h @@ -23,6 +23,7 @@ namespace Swift { String getAvatarHash(const JID&) const; boost::filesystem::path getAvatarPath(const JID&) const; + void setAvatar(const JID&, const ByteArray& avatar); public: boost::signal<void (const JID&, const String&)> onAvatarChanged; diff --git a/Swiften/Elements/VCardUpdate.h b/Swiften/Elements/VCardUpdate.h index b6c8ebd..6bb79cc 100644 --- a/Swiften/Elements/VCardUpdate.h +++ b/Swiften/Elements/VCardUpdate.h @@ -6,7 +6,7 @@ namespace Swift { class VCardUpdate : public Payload { public: - VCardUpdate() {} + VCardUpdate(const String& photoHash = "") : photoHash_(photoHash) {} void setPhotoHash(const String& photoHash) { photoHash_ = photoHash; } const String& getPhotoHash() { return photoHash_; } |