diff --git a/src/channel.cpp b/src/channel.cpp index 51b599b44..da7643d62 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -38,6 +38,13 @@ void Channel::addMessage(std::shared_ptr message) { std::shared_ptr deleted; + const QString &username = message->username; + + if (!username.isEmpty()) { + // TODO: Add recent chatters display name. This should maybe be a setting + this->addRecentChatter(username); + } + // if (_loggingChannel.get() != nullptr) { // _loggingChannel->append(message); // } @@ -49,6 +56,24 @@ void Channel::addMessage(std::shared_ptr message) this->messageAppended(message); } +void Channel::addRecentChatter(const QString &username) +{ + std::lock_guard lock(this->recentChattersMutex); + + this->recentChatters.insert(username); +} + +std::set Channel::getUsernamesForCompletions() +{ + std::set usernames; + + this->recentChattersMutex.lock(); + usernames.insert(this->recentChatters.begin(), this->recentChatters.end()); + this->recentChattersMutex.unlock(); + + return usernames; +} + bool Channel::canSendMessage() const { return false; diff --git a/src/channel.hpp b/src/channel.hpp index ceca68f28..685503dbf 100644 --- a/src/channel.hpp +++ b/src/channel.hpp @@ -13,6 +13,7 @@ #include #include +#include namespace chatterino { namespace messages { @@ -30,16 +31,21 @@ public: virtual bool isEmpty() const; messages::LimitedQueueSnapshot getMessageSnapshot(); - // methods void addMessage(messages::SharedMessage message); + void addRecentChatter(const QString &username); + + std::set getUsernamesForCompletions(); + QString name; QStringList modList; + std::mutex recentChattersMutex; + std::set recentChatters; + virtual bool canSendMessage() const; virtual void sendMessage(const QString &message); private: - // variables messages::LimitedQueue messages; // std::shared_ptr loggingChannel; diff --git a/src/channelmanager.cpp b/src/channelmanager.cpp index 6371de46e..3df5e97e4 100644 --- a/src/channelmanager.cpp +++ b/src/channelmanager.cpp @@ -5,6 +5,8 @@ using namespace chatterino::twitch; namespace chatterino { +ChannelManager *ChannelManager::instance = nullptr; + ChannelManager::ChannelManager(WindowManager &_windowManager, IrcManager &_ircManager) : windowManager(_windowManager) , ircManager(_ircManager) @@ -12,6 +14,7 @@ ChannelManager::ChannelManager(WindowManager &_windowManager, IrcManager &_ircMa , mentionsChannel(new TwitchChannel(_ircManager, "/mentions", true)) , emptyChannel(new TwitchChannel(_ircManager, "", true)) { + ChannelManager::instance = this; } const std::vector> ChannelManager::getItems() diff --git a/src/channelmanager.hpp b/src/channelmanager.hpp index 0484360c4..02200e646 100644 --- a/src/channelmanager.hpp +++ b/src/channelmanager.hpp @@ -16,6 +16,8 @@ class ChannelManager public: explicit ChannelManager(WindowManager &_windowManager, IrcManager &_ircManager); + static ChannelManager *instance; + WindowManager &windowManager; IrcManager &ircManager; diff --git a/src/completionmanager.cpp b/src/completionmanager.cpp index 51dfa41a3..520cf1d6e 100644 --- a/src/completionmanager.cpp +++ b/src/completionmanager.cpp @@ -1,11 +1,12 @@ #include "completionmanager.hpp" +#include "channelmanager.hpp" #include "common.hpp" #include "debug/log.hpp" #include "emotemanager.hpp" namespace chatterino { -CompletionModel::CompletionModel(const std::string &_channelName) +CompletionModel::CompletionModel(const QString &_channelName) : channelName(_channelName) { } @@ -39,14 +40,14 @@ void CompletionModel::refresh() // Channel-specific: BTTV Channel Emotes std::vector &bttvChannelEmoteCodes = - emoteManager.bttvChannelEmoteCodes[this->channelName]; + emoteManager.bttvChannelEmoteCodes[this->channelName.toStdString()]; for (const auto &m : bttvChannelEmoteCodes) { this->addString(m); } // Channel-specific: FFZ Channel Emotes std::vector &ffzChannelEmoteCodes = - emoteManager.ffzChannelEmoteCodes[this->channelName]; + emoteManager.ffzChannelEmoteCodes[this->channelName.toStdString()]; for (const auto &m : ffzChannelEmoteCodes) { this->addString(m); } @@ -57,7 +58,17 @@ void CompletionModel::refresh() this->addString(":" + m + ":"); } - // TODO: Add Channel-specific: Usernames + // Channel-specific: Usernames + auto *channelManager = ChannelManager::instance; + auto c = channelManager->getTwitchChannel(this->channelName); + if (!c) { + return; + } + auto usernames = c->getUsernamesForCompletions(); + for (const auto &username : usernames) { + this->addString(username); + this->addString('@' + username); + } } void CompletionModel::addString(const std::string &str) @@ -66,6 +77,12 @@ void CompletionModel::addString(const std::string &str) this->emotes.push_back(qS(str) + " "); } +void CompletionModel::addString(const QString &str) +{ + // Always add a space at the end of completions + this->emotes.push_back(str + " "); +} + CompletionModel *CompletionManager::createModel(const std::string &channelName) { auto it = this->models.find(channelName); @@ -73,7 +90,7 @@ CompletionModel *CompletionManager::createModel(const std::string &channelName) return it->second; } - CompletionModel *ret = new CompletionModel(channelName); + CompletionModel *ret = new CompletionModel(qS(channelName)); this->models[channelName] = ret; return ret; diff --git a/src/completionmanager.hpp b/src/completionmanager.hpp index 778b80706..e35c027be 100644 --- a/src/completionmanager.hpp +++ b/src/completionmanager.hpp @@ -11,7 +11,7 @@ namespace chatterino { class CompletionModel : public QAbstractListModel { public: - CompletionModel(const std::string &_channelName); + CompletionModel(const QString &_channelName); virtual int columnCount(const QModelIndex & /*parent*/) const override { @@ -33,10 +33,11 @@ public: private: void addString(const std::string &str); + void addString(const QString &str); QVector emotes; - std::string channelName; + QString channelName; }; class CompletionManager