diff options
Diffstat (limited to 'Swift/Controllers/Chat/ChatsManager.cpp')
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 166 |
1 files changed, 130 insertions, 36 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 19400f9..6530a7e 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -32,10 +32,11 @@ #include <Swiften/Roster/XMPPRoster.h> #include <Swiften/StringCodecs/Base64.h> #include <Swiften/VCards/VCardManager.h> #include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h> +#include <Swift/Controllers/Chat/Chattables.h> #include <Swift/Controllers/Chat/ChatController.h> #include <Swift/Controllers/Chat/ChatControllerBase.h> #include <Swift/Controllers/Chat/ChatListWindowChatBoostSerialize.h> #include <Swift/Controllers/Chat/ChatMessageParser.h> #include <Swift/Controllers/Chat/MUCController.h> @@ -64,11 +65,13 @@ namespace Swift { typedef std::pair<JID, ChatController*> JIDChatControllerPair; typedef std::pair<JID, MUCController*> JIDMUCControllerPair; +#ifndef NOT_YET #define RECENT_CHATS "recent_chats" +#endif ChatsManager::ChatsManager( JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, @@ -76,11 +79,13 @@ ChatsManager::ChatsManager( JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, +#ifndef NOT_YET ChatListWindowFactory* chatListWindowFactory, +#endif bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, @@ -93,11 +98,12 @@ ChatsManager::ChatsManager( HistoryController* historyController, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, const std::map<std::string, std::string>& emoticons, - VCardManager* vcardManager) : + VCardManager* vcardManager, + Chattables& chattables) : jid_(jid), joinMUCWindowFactory_(joinMUCWindowFactory), useDelayForLatency_(useDelayForLatency), mucRegistry_(mucRegistry), entityCapsProvider_(entityCapsProvider), @@ -109,11 +115,12 @@ ChatsManager::ChatsManager( historyController_(historyController), whiteboardManager_(whiteboardManager), highlightManager_(highlightManager), emoticons_(emoticons), clientBlockListManager_(clientBlockListManager), - vcardManager_(vcardManager) { + vcardManager_(vcardManager), + chattables_(chattables) { timerFactory_ = timerFactory; eventController_ = eventController; stanzaChannel_ = stanzaChannel; iqRouter_ = iqRouter; chatWindowFactory_ = chatWindowFactory; @@ -125,16 +132,16 @@ ChatsManager::ChatsManager( uiEventStream_ = uiEventStream; mucBookmarkManager_ = nullptr; profileSettings_ = profileSettings; presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1)); uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1)); - +#ifndef NOT_YET chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_); chatListWindow_->onMUCBookmarkActivated.connect(boost::bind(&ChatsManager::handleMUCBookmarkActivated, this, _1)); chatListWindow_->onRecentActivated.connect(boost::bind(&ChatsManager::handleRecentActivated, this, _1)); chatListWindow_->onClearRecentsRequested.connect(boost::bind(&ChatsManager::handleClearRecentsRequested, this)); - +#endif joinMUCWindow_ = nullptr; mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_); mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1)); ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1)); whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2)); @@ -144,22 +151,26 @@ ChatsManager::ChatsManager( roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); roster_->onRosterCleared.connect(boost::bind(&ChatsManager::handleRosterCleared, this)); + chattables_.onActivated.connect(boost::bind(&ChatsManager::handleChattableActivated, this, _1)); + settings_->onSettingChanged.connect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); setupBookmarks(); +#ifndef NOT_YET loadRecents(); - +#endif autoAcceptMUCInviteDecider_ = new AutoAcceptMUCInviteDecider(jid.getDomain(), roster_, settings_); } ChatsManager::~ChatsManager() { settings_->onSettingChanged.disconnect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); + chattables_.onActivated.disconnect(boost::bind(&ChatsManager::handleChattableActivated, this, _1)); roster_->onJIDAdded.disconnect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); roster_->onJIDRemoved.disconnect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); roster_->onJIDUpdated.disconnect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); roster_->onRosterCleared.disconnect(boost::bind(&ChatsManager::handleRosterCleared, this)); ftOverview_->onNewFileTransferController.disconnect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1)); @@ -174,10 +185,11 @@ ChatsManager::~ChatsManager() { delete mucBookmarkManager_; delete mucSearchController_; delete autoAcceptMUCInviteDecider_; } +#ifndef NOT_YET void ChatsManager::saveRecents() { std::stringstream serializeStream; boost::archive::text_oarchive oa(serializeStream); std::vector<ChatListWindow::Chat> recentsLimited = std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end()); if (recentsLimited.size() > 25) { @@ -206,10 +218,11 @@ void ChatsManager::saveRecents() { void ChatsManager::handleClearRecentsRequested() { recentChats_.clear(); saveRecents(); handleUnreadCountChanged(nullptr); } +#endif void ChatsManager::handleJIDAddedToRoster(const JID &jid) { updatePresenceReceivingStateOnChatController(jid); } @@ -240,10 +253,11 @@ void ChatsManager::updatePresenceReceivingStateOnChatController(const JID &jid) controller->setContactIsReceivingPresence(true); } } } +#ifndef NOT_YET ChatListWindow::Chat ChatsManager::updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const { ChatListWindow::Chat fixedChat = chat; if (fixedChat.isMUC) { if (mucControllers_.find(fixedChat.jid.toBare()) != mucControllers_.end()) { fixedChat.statusType = StatusShow::Online; @@ -307,47 +321,60 @@ void ChatsManager::loadRecents() { prependRecent(chat); } } handleUnreadCountChanged(nullptr); } +#endif void ChatsManager::setupBookmarks() { if (!mucBookmarkManager_) { mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_); mucBookmarkManager_->onBookmarksReady.connect(boost::bind(&ChatsManager::handleBookmarksReady, this)); mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&ChatsManager::handleMUCBookmarkAdded, this, _1)); mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&ChatsManager::handleMUCBookmarkRemoved, this, _1)); +#ifndef NOT_YET if (chatListWindow_) { chatListWindow_->setBookmarksEnabled(false); chatListWindow_->clearBookmarks(); } +#endif } } void ChatsManager::handleBookmarksReady() { +#ifndef NOT_YET if (chatListWindow_) { chatListWindow_->setBookmarksEnabled(true); } +#endif } void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { if (bookmark.getRoom().isBare() && !bookmark.getRoom().getNode().empty()) { std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom()); if (it == mucControllers_.end() && bookmark.getAutojoin()) { - handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false ); + handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false); } +#ifndef NOT_YET + //Only one entry of the bookmark should exist + chatListWindow_->removeMUCBookmark(bookmark); chatListWindow_->addMUCBookmark(bookmark); +#endif + chattables_.addJID(bookmark.getRoom(), Chattables::State::Type::Room); } } void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { +#ifndef NOT_YET chatListWindow_->removeMUCBookmark(bookmark); +#endif } +#ifndef NOT_YET ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage) { - int unreadCount = 0; + size_t unreadCount = 0; if (mucRegistry_->isMUC(jid)) { MUCController* controller = mucControllers_[jid.toBare()]; StatusShow::Type type = StatusShow::None; std::string nick = ""; std::string password = ""; @@ -386,12 +413,14 @@ ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const 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); } } +#endif void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity, bool isMUC) { +#ifndef NOT_YET const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC; ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage); /* FIXME: handle nick changes */ appendRecent(chat); handleUnreadCountChanged(nullptr); @@ -403,19 +432,24 @@ void ChatsManager::handleChatActivity(const JID& jid, const std::string& activit auto chatListWindowIter = std::find_if(recentChats_.begin(), recentChats_.end(), [&](const ChatListWindow::Chat& chatListWindow) { return jid == (chatListWindow.jid); }); if (chatListWindowIter != recentChats_.end() && (mucControllers_[jid]->isImpromptu() || !chatListWindowIter->impromptuJIDs.empty())) { mucControllers_[jid]->setChatWindowTitle(chatListWindowIter->getTitle()); } } +#endif } void ChatsManager::handleChatClosed(const JID& /*jid*/) { cleanupPrivateMessageRecents(); +#ifndef NOT_YET chatListWindow_->setRecents(recentChats_); +#endif } +#ifndef NOT_YET + void ChatsManager::handleUnreadCountChanged(ChatControllerBase* controller) { - int unreadTotal = 0; + size_t unreadTotal = 0; bool controllerIsMUC = dynamic_cast<MUCController*>(controller); bool isPM = controller && !controllerIsMUC && mucRegistry_->isMUC(controller->getToJID().toBare()); for (ChatListWindow::Chat& chatItem : recentChats_) { bool match = false; if (controller) { @@ -443,11 +477,13 @@ boost::optional<ChatListWindow::Chat> ChatsManager::removeExistingChat(const Cha return boost::optional<ChatListWindow::Chat>(existingChat); } else { return boost::optional<ChatListWindow::Chat>(); } } +#endif +#ifndef NOT_YET 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) { @@ -481,27 +517,42 @@ void ChatsManager::prependRecent(const ChatListWindow::Chat& chat) { mergedChat.inviteesNames.insert(oldChat->inviteesNames.begin(), oldChat->inviteesNames.end()); mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); } recentChats_.push_back(mergedChat); } +#endif void ChatsManager::handleUserLeftMUC(MUCController* mucController) { std::map<JID, MUCController*>::iterator it; for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) { if ((*it).second == mucController) { +#ifndef NOT_YET for (ChatListWindow::Chat& chat : recentChats_) { if (chat.isMUC && chat.jid == (*it).first) { chat.statusType = StatusShow::None; } } +#endif + const auto& jid = it->first; + auto state = chattables_.getState(jid); + state.status = StatusShow::None; + chattables_.setState(jid, state); + //If user deletes bookmark from chatListWindow_ and then decides to leave the room, or if the server doesn't support bookmarks, the bookmark will not exist. + if (auto bookmarkFound = mucBookmarkManager_->lookupBookmark(jid)) { + MUCBookmark newBookmark(bookmarkFound.get()); + newBookmark.setAutojoin(false); + mucBookmarkManager_->replaceBookmark(bookmarkFound.get(), newBookmark); + } mucControllers_.erase(it); delete mucController; break; } } cleanupPrivateMessageRecents(); +#ifndef NOT_YET chatListWindow_->setRecents(recentChats_); +#endif } void ChatsManager::handleSettingChanged(const std::string& settingPath) { if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); @@ -574,21 +625,21 @@ void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) { 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); + MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), 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()); + handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), 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_); @@ -598,17 +649,19 @@ void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) { joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_)); joinMUCWindow_->show(); } } +#ifndef NOT_YET void ChatsManager::markAllRecentsOffline() { for (ChatListWindow::Chat& chat : recentChats_) { chat.setStatusType(StatusShow::None); } chatListWindow_->setRecents(recentChats_); } +#endif void ChatsManager::handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason) { JID reuseChatInvite = chatController->getToJID(); chatControllers_.erase(chatController->getToJID()); delete chatController; @@ -618,30 +671,31 @@ void ChatsManager::handleTransformChatToMUC(ChatController* chatController, Chat // create new muc JID roomJID = JID(idGenerator_.generateID(), localMUCServiceJID_); // join muc - MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true, chatWindow); + MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), true, true, chatWindow); mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, jidsToInvite, reason, boost::optional<JID>(reuseChatInvite))); } /** * If a resource goes offline, release bound chatdialog to that resource. */ void ChatsManager::handlePresenceChange(std::shared_ptr<Presence> newPresence) { if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return; - +#ifndef NOT_YET for (ChatListWindow::Chat& chat : recentChats_) { if (newPresence->getFrom().toBare() == chat.jid.toBare() && !chat.isMUC) { Presence::ref presence = presenceOracle_->getHighestPriorityPresence(chat.jid.toBare()); chat.setStatusType(presence ? presence->getShow() : StatusShow::None); chatListWindow_->setRecents(recentChats_); break; } } - +#endif //if (newPresence->getType() != Presence::Unavailable) return; + JID fullJID(newPresence->getFrom()); std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID); if (it == chatControllers_.end()) return; JID bareJID(fullJID.toBare()); //It doesn't make sense to have two unbound dialogs. @@ -652,25 +706,29 @@ void ChatsManager::handlePresenceChange(std::shared_ptr<Presence> newPresence) { void ChatsManager::setAvatarManager(AvatarManager* avatarManager) { if (avatarManager_) { avatarManager_->onAvatarChanged.disconnect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1)); } avatarManager_ = avatarManager; +#ifndef NOT_YET for (ChatListWindow::Chat& chat : recentChats_) { if (!chat.isMUC) { chat.setAvatarPath(avatarManager_->getAvatarPath(chat.jid)); } } +#endif avatarManager_->onAvatarChanged.connect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1)); } void ChatsManager::handleAvatarChanged(const JID& jid) { +#ifndef NOT_YET for (ChatListWindow::Chat& chat : recentChats_) { if (!chat.isMUC && jid.toBare() == chat.jid.toBare()) { chat.setAvatarPath(avatarManager_->getAvatarPath(jid)); break; } } +#endif } void ChatsManager::setServerDiscoInfo(std::shared_ptr<DiscoInfo> info) { serverDiscoInfo_ = info; for (JIDChatControllerPair pair : chatControllers_) { @@ -703,14 +761,15 @@ void ChatsManager::setOnline(bool enabled) { localMUCServiceFinderWalker_->onServiceFound.connect(boost::bind(&ChatsManager::handleLocalServiceFound, this, _1, _2)); localMUCServiceFinderWalker_->onWalkAborted.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this)); localMUCServiceFinderWalker_->onWalkComplete.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this)); localMUCServiceFinderWalker_->beginWalk(); } - +#ifndef NOT_YET if (chatListWindow_) { chatListWindow_->setBookmarksEnabled(enabled); } +#endif } void ChatsManager::handleChatRequest(const std::string &contact) { ChatController* controller = getChatControllerOrFindAnother(JID(contact)); controller->activateChatWindow(); @@ -730,16 +789,18 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) } ChatController* ChatsManager::createNewChatController(const JID& contact) { assert(chatControllers_.find(contact) == chatControllers_.end()); std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getConfiguration(), ChatMessageParser::Mode::Chat); /* 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_, timerFactory_, eventController_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_); + auto controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, timerFactory_, eventController_, entityCapsProvider_, userWantsReceipts_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_, settings_, chattables_); 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)); +#ifndef NOT_YET controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); +#endif controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3)); updatePresenceReceivingStateOnChatController(contact); controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty()); return controller; } @@ -784,24 +845,12 @@ void ChatsManager::rebindControllerJID(const JID& from, const JID& to) { chatControllers_[to] = chatControllers_[from]; chatControllers_.erase(from); chatControllers_[to]->setToJID(to); } -MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<std::string>& password, const boost::optional<std::string>& nickMaybe, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow) { +MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<std::string>& password, const boost::optional<std::string>& nickMaybe, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow) { MUC::ref muc; - if (addAutoJoin) { - MUCBookmark bookmark(mucJID, mucJID.getNode()); - bookmark.setAutojoin(true); - if (nickMaybe) { - bookmark.setNick(*nickMaybe); - } - if (password) { - bookmark.setPassword(*password); - } - mucBookmarkManager_->addBookmark(bookmark); - } - std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID); if (it != mucControllers_.end()) { if (stanzaChannel_->isAvailable()) { it->second->rejoin(); } @@ -819,11 +868,15 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = nullptr; if (reuseChatwindow) { chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow); } std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getConfiguration(), ChatMessageParser::Mode::GroupChat); /* a message parser that knows this is a room/MUC (not a chat) */ - controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, nickResolver_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_); + controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, nickResolver_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_, settings_, chattables_); + chattables_.addJID(muc->getJID(), Chattables::State::Type::Room); + auto state = chattables_.getState(muc->getJID()); + state.status = StatusShow::Online; + chattables_.setState(muc->getJID(), state); if (chatWindowFactoryAdapter) { /* The adapters are only passed to chat windows, which are deleted in their * controllers' dtor, which are deleted in ChatManager's dtor. The adapters * are also deleted there.*/ chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter; @@ -833,26 +886,46 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller)); controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true)); controller->onUserNicknameChanged.connect(boost::bind(&ChatsManager::handleUserNicknameChanged, this, controller, _1, _2)); controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true)); - controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); +#ifndef NOT_YET + controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); +#endif if (!stanzaChannel_->isAvailable()) { /* When online, the MUC is added to the registry in MUCImpl::internalJoin. This method is not * called when Swift is offline, so we add it here as only MUCs in the registry are rejoined * when going back online. */ mucRegistry_->addMUC(mucJID.toBare()); } handleChatActivity(mucJID.toBare(), "", true); } - +#ifndef NOT_YET auto chatListWindowIter = std::find_if(recentChats_.begin(), recentChats_.end(), [&](const ChatListWindow::Chat& chatListWindow) { return mucJID == (chatListWindow.jid); }); if (chatListWindowIter != recentChats_.end() && (mucControllers_[mucJID]->isImpromptu() || !chatListWindowIter->impromptuJIDs.empty())) { mucControllers_[mucJID]->setChatWindowTitle(chatListWindowIter->getTitle()); } - +#endif + if (auto existingBookmark = mucBookmarkManager_->lookupBookmark(mucJID)) { + if (!existingBookmark->getAutojoin()) { + MUCBookmark newbookmark(existingBookmark.get()); + newbookmark.setAutojoin(true); + mucBookmarkManager_->replaceBookmark(*existingBookmark, newbookmark); + } + } + else { + MUCBookmark bookmark(mucJID, mucJID.getNode()); + bookmark.setAutojoin(true); + if (nickMaybe) { + bookmark.setNick(*nickMaybe); + } + if (password) { + bookmark.setPassword(*password); + } + mucBookmarkManager_->addBookmark(bookmark); + } mucControllers_[mucJID]->showChatWindow(); return muc; } void ChatsManager::handleSearchMUCRequest() { @@ -958,15 +1031,15 @@ void ChatsManager::handleIncomingMessage(std::shared_ptr<Message> incomingMessag ChatController* controller = getChatControllerIfExists(fromJID); if (controller) { ChatWindow* window = controller->detachChatWindow(); chatControllers_.erase(fromJID); delete controller; - handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true, window); + handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, true, window); return; } } else { - handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true); + handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, true); return; } } //if not a mucroom @@ -1021,11 +1094,11 @@ void ChatsManager::handleWhiteboardStateChange(const JID& contact, const ChatWin chatListWindow_->addWhiteboardSession(chat); } else { chatListWindow_->removeWhiteboardSession(contact.toBare()); } } - +#ifndef NOT_YET void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) { if (chat.isMUC && !chat.impromptuJIDs.empty()) { typedef std::pair<std::string, JID> StringJIDPair; std::vector<JID> inviteJIDs; for (StringJIDPair pair : chat.impromptuJIDs) { @@ -1034,17 +1107,34 @@ void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) { uiEventStream_->send(std::make_shared<CreateImpromptuMUCUIEvent>(inviteJIDs, chat.jid, "")); } else if (chat.isMUC) { bool isImpromptu = (!chat.inviteesNames.empty() || !chat.impromptuJIDs.empty()); /* FIXME: This means that recents requiring passwords will just flat-out not work */ - uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick, false, false, isImpromptu)); + uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick, false, isImpromptu)); } else { uiEventStream_->send(std::make_shared<RequestChatUIEvent>(chat.jid)); } } +#endif + +void ChatsManager::handleChattableActivated(const JID& jid) { + auto state = chattables_.getState(jid); + if (state.type == Chattables::State::Type::Person) { + uiEventStream_->send(std::make_shared<RequestChatUIEvent>(jid)); + } + else if (state.type == Chattables::State::Type::Room) { + if (auto foundBookmark = mucBookmarkManager_->lookupBookmark(jid)) { + handleMUCBookmarkActivated(foundBookmark.get()); + } + else { + uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(jid, boost::optional<std::string>(), boost::optional<std::string>())); // Just a quick hack to reuse already open MUCs + } + } +} + void ChatsManager::handleLocalServiceFound(const JID& service, std::shared_ptr<DiscoInfo> info) { for (DiscoInfo::Identity identity : info->getIdentities()) { if ((identity.getCategory() == "directory" && identity.getType() == "chatroom") || (identity.getCategory() == "conference" @@ -1066,21 +1156,25 @@ void ChatsManager::handleLocalServiceWalkFinished() { controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported); } onImpromptuMUCServiceDiscovered(impromptuMUCSupported); } +#ifndef NOT_YET std::vector<ChatListWindow::Chat> ChatsManager::getRecentChats() const { return std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end()); } +#endif std::vector<Contact::ref> Swift::ChatsManager::getContacts(bool withMUCNicks) { std::vector<Contact::ref> result; +#ifndef NOT_YET for (ChatListWindow::Chat chat : recentChats_) { if (!chat.isMUC) { result.push_back(std::make_shared<Contact>(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath)); } } +#endif if (withMUCNicks) { /* collect MUC nicks */ typedef std::map<JID, MUCController*>::value_type Item; for (const Item& item : mucControllers_) { JID mucJID = item.second->getToJID(); |
Swift