diff options
| author | Richard Maudsley <richard.maudsley@isode.com> | 2014-07-11 14:03:57 (GMT) |
|---|---|---|
| committer | Swift Review <review@swift.im> | 2014-07-27 14:09:54 (GMT) |
| commit | fde89fee2175e7cbeda9262e7517f153de76e1b8 (patch) | |
| tree | 9834c5d04a66c84fe50b1719e16c3749123fa8ff /Swift/Controllers/Chat/ChatsManager.cpp | |
| parent | 9353d3c692e1cd37bdd15b8dbe75b92be5eaa1c0 (diff) | |
| download | swift-contrib-fde89fee2175e7cbeda9262e7517f153de76e1b8.zip swift-contrib-fde89fee2175e7cbeda9262e7517f153de76e1b8.tar.bz2 | |
Fix recent chat items not being shown for private MUC messages.
Test-Information:
Send private message and verify that the private message item in the recents list is erased when the user leaves the MUC and the chat window is closed. Check that other recent items are not removed. Check that private message recent items are not saved and loaded when the application is restarted.
Change-Id: I62b9d324143d2e77ed98592cf37fb681165285c2
Diffstat (limited to 'Swift/Controllers/Chat/ChatsManager.cpp')
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 8a077d1..3db1327 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -218,18 +218,27 @@ void ChatsManager::saveRecents() { if (recentsLimited.size() > 25) { recentsLimited.erase(recentsLimited.begin() + 25, recentsLimited.end()); } if (eagleMode_) { foreach(ChatListWindow::Chat& chat, recentsLimited) { chat.activity = ""; } } + class RemoveRecent { + public: + static bool ifPrivateMessage(const ChatListWindow::Chat& chat) { + return chat.isPrivateMessage; + } + }; + + recentsLimited.erase(std::remove_if(recentsLimited.begin(), recentsLimited.end(), RemoveRecent::ifPrivateMessage), recentsLimited.end()); + oa << recentsLimited; std::string serializedStr = Base64::encode(createByteArray(serializeStream.str())); profileSettings_->storeString(RECENT_CHATS, serializedStr); } void ChatsManager::handleClearRecentsRequested() { recentChats_.clear(); saveRecents(); handleUnreadCountChanged(NULL); @@ -304,19 +313,19 @@ void ChatsManager::loadRecents() { if (!jid.isValid()) { continue; } std::string activity(recent[1]); bool isMUC = recent[2] == "true"; std::string nick(recent[3]); StatusShow::Type type = StatusShow::None; boost::filesystem::path path; - ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, nick); + ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, false, nick); chat = updateChatStatusAndAvatarHelper(chat); prependRecent(chat); } } else if (!recentsString.empty()){ // boost searilaize based format ByteArray debase64 = Base64::decode(recentsString); std::vector<ChatListWindow::Chat> recentChats; std::stringstream deserializeStream(std::string(reinterpret_cast<const char*>(vecptr(debase64)), debase64.size())); try { @@ -362,70 +371,72 @@ void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false ); } chatListWindow_->addMUCBookmark(bookmark); } void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { chatListWindow_->removeMUCBookmark(bookmark); } -ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity) { +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, nick, password); + ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); typedef std::pair<std::string, JID> StringJIDPair; std::map<std::string, JID> participants = controller->getParticipantJIDs(); chat.impromptuJIDs = participants; return chat; } } - return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, nick, password); + 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_->getHighestPriorityPresence(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); + 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) { - if (mucRegistry_->isMUC(jid.toBare()) && !isMUC) { - /* Don't include PMs in MUC rooms.*/ - return; - } - ChatListWindow::Chat chat = createChatListChatItem(jid, activity); + const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC; + ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage); /* FIXME: handle nick changes */ appendRecent(chat); handleUnreadCountChanged(NULL); saveRecents(); } +void ChatsManager::handleChatClosed(const JID& /*jid*/) { + cleanupPrivateMessageRecents(); + chatListWindow_->setRecents(recentChats_); +} + void ChatsManager::handleUnreadCountChanged(ChatControllerBase* controller) { int unreadTotal = 0; bool controllerIsMUC = dynamic_cast<MUCController*>(controller); bool isPM = controller && !controllerIsMUC && mucRegistry_->isMUC(controller->getToJID().toBare()); foreach (ChatListWindow::Chat& chatItem, recentChats_) { bool match = false; if (controller) { /* Matching MUC item */ match |= chatItem.isMUC == controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); @@ -448,18 +459,36 @@ 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_; + foreach (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()) { mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); } recentChats_.push_front(mergedChat); } @@ -473,27 +502,27 @@ void ChatsManager::prependRecent(const ChatListWindow::Chat& chat) { } void ChatsManager::handleUserLeftMUC(MUCController* mucController) { std::map<JID, MUCController*>::iterator it; for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) { if ((*it).second == mucController) { foreach (ChatListWindow::Chat& chat, recentChats_) { if (chat.isMUC && chat.jid == (*it).first) { chat.statusType = StatusShow::None; - chatListWindow_->setRecents(recentChats_); - break; } } mucControllers_.erase(it); delete mucController; - return; + 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; } } @@ -695,18 +724,19 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) } ChatController* ChatsManager::createNewChatController(const JID& contact) { assert(chatControllers_.find(contact) == chatControllers_.end()); boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), false); /* a message parser that knows this is a chat (not a room/MUC) */ ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_); chatControllers_[contact] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); + controller->onWindowClosed.connect(boost::bind(&ChatsManager::handleChatClosed, this, contact)); controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3)); updatePresenceReceivingStateOnChatController(contact); controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty()); return controller; } ChatController* ChatsManager::getChatControllerOrCreate(const JID &contact) { ChatController* controller = getChatControllerIfExists(contact); |
Swift