diff options
author | Joanna Hulboj <joanna.hulboj@isode.com> | 2017-03-13 21:51:04 (GMT) |
---|---|---|
committer | Kevin Smith <kevin.smith@isode.com> | 2017-05-04 10:34:00 (GMT) |
commit | cfea60eda7f3ce5fa10ed92c50c19fc1ee264eb1 (patch) | |
tree | fb2564927189eb1cc8e28ac82fd96f6161b54d31 /Swift/Controllers/Chat/ChatsManager.cpp | |
parent | dc70dbb6af039fba8f7a1cece8db4bb119deaabd (diff) | |
download | swift-cfea60eda7f3ce5fa10ed92c50c19fc1ee264eb1.zip swift-cfea60eda7f3ce5fa10ed92c50c19fc1ee264eb1.tar.bz2 |
Fix recent chat entries being incorrectly displayed
Recent chat entries were displayed as a randomly generated numbers instead of
impromptus (if invitees were offline).
Title displayed in the Recent Chat List for MUC is now based on both the
occupants and invitees. To do that a collection with all the invitees is
being stored (new) along the occupants (existing).
Test-Information:
From Swift menu choose Actions, Start Chat... Add some offline contacts
to the List of Participants and press Finish. Recent chat entry will
have correct name (combined of contact names).
Change-Id: Ie076165e8dbb493aa261cc49ca3ab1e0c1c542a8
Diffstat (limited to 'Swift/Controllers/Chat/ChatsManager.cpp')
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index db3b3b7..9db343f 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -40,89 +40,92 @@ #include <Swiften/StringCodecs/Base64.h> #include <Swiften/VCards/VCardManager.h> #include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h> #include <Swift/Controllers/Chat/ChatController.h> #include <Swift/Controllers/Chat/ChatControllerBase.h> #include <Swift/Controllers/Chat/ChatMessageParser.h> #include <Swift/Controllers/Chat/MUCController.h> #include <Swift/Controllers/Chat/MUCSearchController.h> #include <Swift/Controllers/Chat/UserSearchController.h> #include <Swift/Controllers/FileTransfer/FileTransferController.h> #include <Swift/Controllers/FileTransfer/FileTransferOverview.h> #include <Swift/Controllers/ProfileSettingsProvider.h> #include <Swift/Controllers/SettingConstants.h> #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> #include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h> #include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h> #include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h> #include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> #include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> #include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h> #include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h> #include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h> #include <Swift/Controllers/WhiteboardManager.h> #include <Swift/Controllers/XMPPEvents/EventController.h> -BOOST_CLASS_VERSION(Swift::ChatListWindow::Chat, 1) +BOOST_CLASS_VERSION(Swift::ChatListWindow::Chat, 2) namespace boost { namespace serialization { template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) { std::string jidStr = jid.toString(); ar << jidStr; } template<class Archive> void load(Archive& ar, Swift::JID& jid, const unsigned int /*version*/) { std::string stringJID; ar >> stringJID; jid = Swift::JID(stringJID); } template<class Archive> inline void serialize(Archive& ar, Swift::JID& t, const unsigned int file_version){ split_free(ar, t, file_version); } template<class Archive> void serialize(Archive& ar, Swift::ChatListWindow::Chat& chat, const unsigned int version) { ar & chat.jid; ar & chat.chatName; ar & chat.activity; ar & chat.isMUC; ar & chat.nick; ar & chat.impromptuJIDs; if (version > 0) { ar & chat.password; } + if (version > 1) { + ar & chat.inviteesNames; + } } } } namespace Swift { typedef std::pair<JID, ChatController*> JIDChatControllerPair; typedef std::pair<JID, MUCController*> JIDMUCControllerPair; #define RECENT_CHATS "recent_chats" ChatsManager::ChatsManager( JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, @@ -375,60 +378,66 @@ void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { } chatListWindow_->addMUCBookmark(bookmark); } void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { chatListWindow_->removeMUCBookmark(bookmark); } ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage) { int unreadCount = 0; if (mucRegistry_->isMUC(jid)) { MUCController* controller = mucControllers_[jid.toBare()]; StatusShow::Type type = StatusShow::None; std::string nick = ""; std::string password = ""; if (controller) { unreadCount = controller->getUnreadCount(); if (controller->isJoined()) { type = StatusShow::Online; } nick = controller->getNick(); if (controller->getPassword()) { password = *controller->getPassword(); } if (controller->isImpromptu()) { ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); std::map<std::string, JID> participants = controller->getParticipantJIDs(); chat.impromptuJIDs = participants; + + std::map<JID, std::string> participantsNames; + for (auto& i : invitees_[jid]) { + participantsNames.emplace(i, roster_->getNameForJID(i)); + } + chat.inviteesNames = participantsNames; return chat; } } return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); } else { ChatController* controller = getChatControllerIfExists(jid, false); if (controller) { unreadCount = controller->getUnreadCount(); } JID bareishJID = mucRegistry_->isMUC(jid.toBare()) ? jid : jid.toBare(); Presence::ref presence = presenceOracle_->getAccountPresence(bareishJID); StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; boost::filesystem::path avatarPath = avatarManager_ ? avatarManager_->getAvatarPath(bareishJID) : boost::filesystem::path(); return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false, privateMessage); } } void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity, bool isMUC) { const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC; ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage); /* FIXME: handle nick changes */ appendRecent(chat); handleUnreadCountChanged(nullptr); saveRecents(); } void ChatsManager::handleChatClosed(const JID& /*jid*/) { cleanupPrivateMessageRecents(); chatListWindow_->setRecents(recentChats_); } @@ -461,70 +470,72 @@ boost::optional<ChatListWindow::Chat> ChatsManager::removeExistingChat(const Cha if (result != recentChats_.end()) { ChatListWindow::Chat existingChat = *result; recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end()); return boost::optional<ChatListWindow::Chat>(existingChat); } else { return boost::optional<ChatListWindow::Chat>(); } } void ChatsManager::cleanupPrivateMessageRecents() { /* if we leave a MUC and close a PM, remove it's recent chat entry */ const std::list<ChatListWindow::Chat> chats = recentChats_; for (const ChatListWindow::Chat& chat : chats) { if (chat.isPrivateMessage) { typedef std::map<JID, MUCController*> ControllerMap; ControllerMap::iterator muc = mucControllers_.find(chat.jid.toBare()); if (muc == mucControllers_.end() || !muc->second->isJoined()) { ChatController* chatController = getChatControllerIfExists(chat.jid); if (!chatController || !chatController->hasOpenWindow()) { removeExistingChat(chat); break; } } } } } void ChatsManager::appendRecent(const ChatListWindow::Chat& chat) { boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); ChatListWindow::Chat mergedChat = chat; - if (oldChat && !oldChat->impromptuJIDs.empty()) { + if (oldChat) { + mergedChat.inviteesNames.insert(oldChat->inviteesNames.begin(), oldChat->inviteesNames.end()); mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); } recentChats_.push_front(mergedChat); } void ChatsManager::prependRecent(const ChatListWindow::Chat& chat) { boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); ChatListWindow::Chat mergedChat = chat; - if (oldChat && !oldChat->impromptuJIDs.empty()) { + if (oldChat) { + mergedChat.inviteesNames.insert(oldChat->inviteesNames.begin(), oldChat->inviteesNames.end()); mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); } recentChats_.push_back(mergedChat); } void ChatsManager::handleUserLeftMUC(MUCController* mucController) { std::map<JID, MUCController*>::iterator it; for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) { if ((*it).second == mucController) { for (ChatListWindow::Chat& chat : recentChats_) { if (chat.isMUC && chat.jid == (*it).first) { chat.statusType = StatusShow::None; } } mucControllers_.erase(it); delete mucController; break; } } cleanupPrivateMessageRecents(); chatListWindow_->setRecents(recentChats_); } void ChatsManager::handleSettingChanged(const std::string& settingPath) { if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); return; } } @@ -563,60 +574,64 @@ void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) { std::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = std::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event); if (addMUCBookmarkEvent) { mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark()); return; } std::shared_ptr<SendFileUIEvent> sendFileEvent = std::dynamic_pointer_cast<SendFileUIEvent>(event); if (sendFileEvent) { JID fileReceiver = sendFileEvent->getJID(); if (fileReceiver.isBare()) { // See if there is a chat controller for a conversation with a bound // full JID. Check if this JID supports file transfer and use it instead // of the bare JID. ChatController* controller = getChatControllerIfExists(fileReceiver, false); if (controller) { JID controllerJID = controller->getToJID(); if (!controllerJID.isBare() && (FeatureOracle(entityCapsProvider_, presenceOracle_).isFileTransferSupported(controllerJID) == Yes)) { fileReceiver = controllerJID; } } } ftOverview_->sendFile(fileReceiver, sendFileEvent->getFilename()); return; } std::shared_ptr<CreateImpromptuMUCUIEvent> createImpromptuMUCEvent = std::dynamic_pointer_cast<CreateImpromptuMUCUIEvent>(event); if (createImpromptuMUCEvent) { assert(!localMUCServiceJID_.toString().empty()); // The room JID is random for new impromptu rooms, or a predefined JID for impromptu rooms resumed from the 'Recent chats' list. JID roomJID = createImpromptuMUCEvent->getRoomJID().toString().empty() ? JID(idGenerator_.generateID(), localMUCServiceJID_) : createImpromptuMUCEvent->getRoomJID(); + std::vector<JID> missingJIDsToInvite = createImpromptuMUCEvent->getJIDs(); + for (const JID& jid : missingJIDsToInvite) { + invitees_[roomJID].insert(jid); + } // join muc MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true); mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, createImpromptuMUCEvent->getJIDs(), createImpromptuMUCEvent->getReason(), boost::optional<JID>())); mucControllers_[roomJID]->activateChatWindow(); } std::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = std::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event); if (editMUCBookmarkEvent) { mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark()); } else if (JoinMUCUIEvent::ref joinEvent = std::dynamic_pointer_cast<JoinMUCUIEvent>(event)) { handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu()); mucControllers_[joinEvent->getJID()]->activateChatWindow(); } else if (std::shared_ptr<RequestJoinMUCUIEvent> joinEvent = std::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) { if (!joinMUCWindow_) { joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow(uiEventStream_); joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this)); } joinMUCWindow_->setMUC(joinEvent->getRoom()); joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_)); joinMUCWindow_->show(); } } void ChatsManager::markAllRecentsOffline() { for (ChatListWindow::Chat& chat : recentChats_) { chat.setStatusType(StatusShow::None); } |