From dd6fe37580c5a0d9426312287cb4ed31116d8c4c Mon Sep 17 00:00:00 2001 From: Kevin Smith <git@kismith.co.uk> Date: Sat, 9 Jul 2011 14:45:46 +0100 Subject: Keep MUCs in the recent chats list. Populate them with Available StatusShow::Type when they're joined, and None when they're not. Resolves: #907 diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 0efbdfd..5173a6f 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -10,24 +10,25 @@ #include <boost/algorithm/string.hpp> #include <Swiften/Base/foreach.h> -#include "Swift/Controllers/Chat/ChatController.h" -#include "Swift/Controllers/Chat/MUCSearchController.h" -#include "Swift/Controllers/XMPPEvents/EventController.h" -#include "Swift/Controllers/Chat/MUCController.h" -#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h" -#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h" -#include "Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h" -#include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h" -#include "Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h" -#include "Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h" -#include "Swift/Controllers/UIInterfaces/ChatListWindowFactory.h" -#include "Swift/Controllers/UIInterfaces/JoinMUCWindow.h" -#include "Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h" -#include "Swiften/Presence/PresenceSender.h" -#include "Swiften/Client/NickResolver.h" -#include "Swiften/MUC/MUCManager.h" -#include "Swiften/Elements/ChatState.h" -#include "Swiften/MUC/MUCBookmarkManager.h" +#include <Swift/Controllers/Chat/ChatController.h> +#include <Swift/Controllers/Chat/ChatControllerBase.h> +#include <Swift/Controllers/Chat/MUCSearchController.h> +#include <Swift/Controllers/XMPPEvents/EventController.h> +#include <Swift/Controllers/Chat/MUCController.h> +#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> +#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> +#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h> +#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h> +#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h> +#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h> +#include <Swiften/Presence/PresenceSender.h> +#include <Swiften/Client/NickResolver.h> +#include <Swiften/MUC/MUCManager.h> +#include <Swiften/Elements/ChatState.h> +#include <Swiften/MUC/MUCBookmarkManager.h> #include <Swift/Controllers/ProfileSettingsProvider.h> namespace Swift { @@ -132,8 +133,16 @@ void ChatsManager::loadRecents() { std::string activity(recent[1]); bool isMUC = recent[2] == "true"; std::string nick(recent[3]); - Presence::ref presence = presenceOracle_->getHighestPriorityPresence(jid.toBare()); - StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; + StatusShow::Type type = StatusShow::None; + if (isMUC) { + if (mucControllers_.find(jid.toBare()) != mucControllers_.end()) { + type = StatusShow::Online; + } + } else { + Presence::ref presence = presenceOracle_->getHighestPriorityPresence(jid.toBare()); + type = presence ? presence->getShow() : StatusShow::None; + } + ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, isMUC, nick); prependRecent(chat); } @@ -175,30 +184,58 @@ void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity) { int unreadCount = 0; - ChatController* controller = getChatControllerIfExists(jid, false); - if (controller) { - unreadCount = controller->getUnreadCount(); - } + if (mucRegistry_->isMUC(jid)) { + MUCController* controller = mucControllers_[jid.toBare()]; + StatusShow::Type type = StatusShow::None; + std::string nick = ""; + if (controller) { + unreadCount = controller->getUnreadCount(); + if (controller->isJoined()) { + type = StatusShow::Online; + } + nick = controller->getNick(); + } + return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, true, nick); + + } else { + ChatController* controller = getChatControllerIfExists(jid, false); + if (controller) { + unreadCount = controller->getUnreadCount(); + } - Presence::ref presence = presenceOracle_->getHighestPriorityPresence(jid.toBare()); - StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; - return ChatListWindow::Chat(jid, nickResolver_->jidToNick(jid), activity, unreadCount, type, false); + Presence::ref presence = presenceOracle_->getHighestPriorityPresence(jid.toBare()); + StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; + return ChatListWindow::Chat(jid, nickResolver_->jidToNick(jid), activity, unreadCount, type, false); + } } -void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity) { +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); - /* FIXME: MUC use requires changes here. */ - /* FIXME: handle nick changes */ appendRecent(chat); handleUnreadCountChanged(NULL); saveRecents(); } -void ChatsManager::handleUnreadCountChanged(ChatController* controller) { +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_) { - if (controller && chatItem.jid.toBare() == controller->getToJID().toBare()) { + bool match = false; + if (controller) { + /* Matching MUC item */ + match |= chatItem.isMUC == controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); + /* Matching PM */ + match |= isPM && chatItem.jid == controller->getToJID(); + /* Matching non-PM */ + match |= !isPM && !controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); + } + if (match) { chatItem.setUnreadCount(controller->getUnreadCount()); } unreadTotal += chatItem.unreadCount; @@ -221,6 +258,11 @@ 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; + } + } mucControllers_.erase(it); delete mucController; return; @@ -350,7 +392,7 @@ ChatController* ChatsManager::createNewChatController(const JID& contact) { ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_); chatControllers_[contact] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); - controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1)); + controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); return controller; } @@ -413,10 +455,12 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional mucControllers_[mucJID] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller)); + controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true)); + controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); + handleChatActivity(mucJID.toBare(), "", true); } mucControllers_[mucJID]->showChatWindow(); - /* FIXME: handleChatActivity connection for recents, and changes to that method.*/ } void ChatsManager::handleSearchMUCRequest() { @@ -458,7 +502,12 @@ void ChatsManager::handleMUCBookmarkActivated(const MUCBookmark& mucBookmark) { } void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) { - uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(chat.jid)); + if (chat.isMUC) { + uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(chat.jid, chat.nick)); + } + else { + uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(chat.jid)); + } } diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index be6e575..a8dd599 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -23,6 +23,7 @@ namespace Swift { class EventController; class ChatController; + class ChatControllerBase; class MUCController; class MUCManager; class ChatWindowFactory; @@ -51,9 +52,9 @@ namespace Swift { void setOnline(bool enabled); void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<Message> message); - ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity); private: + ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity); void handleChatRequest(const std::string& contact); void handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& nick, bool addAutoJoin); void handleSearchMUCRequest(); @@ -65,7 +66,7 @@ namespace Swift { void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); void handleUserLeftMUC(MUCController* mucController); void handleBookmarksReady(); - void handleChatActivity(const JID& jid, const std::string& activity); + void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC); void appendRecent(const ChatListWindow::Chat& chat); void prependRecent(const ChatListWindow::Chat& chat); void setupBookmarks(); @@ -74,7 +75,7 @@ namespace Swift { void handleChatMadeRecent(); void handleMUCBookmarkActivated(const MUCBookmark&); void handleRecentActivated(const ChatListWindow::Chat&); - void handleUnreadCountChanged(ChatController* controller); + void handleUnreadCountChanged(ChatControllerBase* controller); ChatController* getChatControllerOrFindAnother(const JID &contact); ChatController* createNewChatController(const JID &contact); diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index ac4689f..2ac6109 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -110,6 +110,14 @@ void MUCController::rejoin() { } } +bool MUCController::isJoined() { + return joined_; +} + +const std::string& MUCController::getNick() { + return nick_; +} + void MUCController::handleJoinTimeoutTick() { receivedActivity(); chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString())); diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 6b05a8e..b8972b1 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -49,6 +49,8 @@ namespace Swift { static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent); static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts); static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts); + bool isJoined(); + const std::string& getNick(); protected: void preSendMessageRequest(boost::shared_ptr<Message> message); -- cgit v0.10.2-6-g49f6