diff --git a/channel.h b/channel.h index 05d067021..b340e4597 100644 --- a/channel.h +++ b/channel.h @@ -33,6 +33,12 @@ public: return ffzChannelEmotes; } + bool + isEmpty() const + { + return name.isEmpty(); + } + const QMutex & getMessageMutex() const { diff --git a/channels.cpp b/channels.cpp index e802f2da8..3b77a3e58 100644 --- a/channels.cpp +++ b/channels.cpp @@ -3,54 +3,75 @@ namespace chatterino { -Channel Channels::whispers(QString("/whispers")); -Channel Channels::mentions(QString("/mentions")); -Channel Channels::empty(QString("")); +std::shared_ptr Channels::whispers(new Channel(QString("/whispers"))); +std::shared_ptr Channels::mentions(new Channel(QString("/mentions"))); +std::shared_ptr Channels::empty(new Channel(QString(""))); -QMap> Channels::channels; +QMap, int>> Channels::channels; +QMutex Channels::channelsMutex; -Channel * -Channels::addChannel(const QString &channel) +const std::vector> +Channels::getItems() { - QString c = channel.toLower(); + QMutexLocker locker(&Channels::channelsMutex); - auto a = Channels::channels.find(c); + int size = Channels::channels.size(); - if (a == Channels::channels.end()) { - auto _c = new Channel(c); - Channels::channels.insert(c, std::tuple(_c, 1)); + std::vector> items(size); - IrcManager::joinChannel(c); - - return _c; - } else { - std::get<1>(a.value())++; + for (auto &item : Channels::channels.values()) { + items.push_back(std::get<0>(item)); } - return std::get<0>(a.value()); + return items; } -Channel * +std::shared_ptr +Channels::addChannel(const QString &channel) +{ + QMutexLocker locker(&Channels::channelsMutex); + + QString channelName = channel.toLower(); + + auto it = Channels::channels.find(channelName); + + if (it == Channels::channels.end()) { + auto channel = std::shared_ptr(new Channel(channelName)); + Channels::channels.insert(channelName, std::make_tuple(channel, 1)); + + IrcManager::sendJoin(channelName); + + return channel; + } + + std::get<1>(it.value())++; + + return std::get<0>(it.value()); +} + +std::shared_ptr Channels::getChannel(const QString &channel) { + QMutexLocker locker(&Channels::channelsMutex); + QString c = channel.toLower(); if (channel.length() > 1 && channel.at(0) == '/') { if (c == "/whispers") { - return &Channels::whispers; + return Channels::whispers; } if (c == "/mentions") { - return &Channels::mentions; + return Channels::mentions; } - return &Channels::empty; + return Channels::empty; } auto a = Channels::channels.find(c); if (a == Channels::channels.end()) { - return NULL; + return Channels::empty; } return std::get<0>(a.value()); @@ -59,6 +80,8 @@ Channels::getChannel(const QString &channel) void Channels::removeChannel(const QString &channel) { + QMutexLocker locker(&Channels::channelsMutex); + if (channel.length() > 1 && channel.at(0) == '/') { return; } @@ -76,7 +99,6 @@ Channels::removeChannel(const QString &channel) if (std::get<1>(a.value()) == 0) { IrcManager::partChannel(c); Channels::channels.remove(c); - delete std::get<0>(a.value()); } } } diff --git a/channels.h b/channels.h index 67dc128fc..0d5fbe499 100644 --- a/channels.h +++ b/channels.h @@ -8,20 +8,28 @@ namespace chatterino { class Channels { public: - static Channel * + static std::shared_ptr getWhispers() { - return &whispers; + return whispers; } - static Channel * + static std::shared_ptr getMentions() { - return &mentions; + return mentions; } - static Channel *addChannel(const QString &channel); - static Channel *getChannel(const QString &channel); + static std::shared_ptr + getEmpty() + { + return empty; + } + + const static std::vector> getItems(); + + static std::shared_ptr addChannel(const QString &channel); + static std::shared_ptr getChannel(const QString &channel); static void removeChannel(const QString &channel); private: @@ -29,11 +37,12 @@ private: { } - static Channel whispers; - static Channel mentions; - static Channel empty; + static std::shared_ptr whispers; + static std::shared_ptr mentions; + static std::shared_ptr empty; - static QMap> channels; + static QMap, int>> channels; + static QMutex channelsMutex; }; } #endif // CHANNELS_H diff --git a/ircmanager.cpp b/ircmanager.cpp index e8fdce5b0..9efa65ee8 100644 --- a/ircmanager.cpp +++ b/ircmanager.cpp @@ -60,8 +60,9 @@ IrcManager::beginConnecting() username + "/blocks?limit=" + 100 + "&client_id=" + oauthClient; + QNetworkAccessManager *manager = new QNetworkAccessManager(); QNetworkRequest req(QUrl(nextLink + "&oauth_token=" + oauthToken)); - QNetworkReply *reply = IrcManager::accessManager.get(req); + QNetworkReply *reply = manager->get(req); QObject::connect(reply, &QNetworkReply::finished, [=] { IrcManager::twitchBlockedUsersMutex.lock(); @@ -86,6 +87,8 @@ IrcManager::beginConnecting() user.value("name").toString().toLower(), true); } IrcManager::twitchBlockedUsersMutex.unlock(); + + manager->deleteLater(); }); } @@ -136,6 +139,12 @@ IrcManager::beginConnecting() delete IrcManager::connection; c->moveToThread(QCoreApplication::instance()->thread()); IrcManager::connection = c; + + auto channels = Channels::getItems(); + + for (auto &channel : channels) { + IrcManager::sendJoin(channel.get()->getName()); + } } else { delete c; } @@ -164,7 +173,7 @@ IrcManager::send(QString raw) } void -IrcManager::joinChannel(const QString &channel) +IrcManager::sendJoin(const QString &channel) { IrcManager::connectionMutex.lock(); if (IrcManager::connection != NULL) { diff --git a/ircmanager.h b/ircmanager.h index 713eb6897..3bc9c1143 100644 --- a/ircmanager.h +++ b/ircmanager.h @@ -38,7 +38,7 @@ public: return accessManager; } - static void joinChannel(const QString &channel); + static void sendJoin(const QString &channel); static void partChannel(const QString &channel); diff --git a/widgets/chatwidget.cpp b/widgets/chatwidget.cpp index 681d9894b..020a7a867 100644 --- a/widgets/chatwidget.cpp +++ b/widgets/chatwidget.cpp @@ -14,7 +14,7 @@ namespace widgets { ChatWidget::ChatWidget(QWidget *parent) : QWidget(parent) - , channel(NULL) + , channel(Channels::getEmpty()) , channelName(QString()) , vbox(this) , header(this) diff --git a/widgets/chatwidget.h b/widgets/chatwidget.h index 5b1782d3c..a8f456ca2 100644 --- a/widgets/chatwidget.h +++ b/widgets/chatwidget.h @@ -29,7 +29,7 @@ public: return view; } - Channel * + std::shared_ptr getChannel() const { return channel; @@ -49,7 +49,7 @@ protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: - Channel *channel; + std::shared_ptr channel; QString channelName; QFont font; diff --git a/widgets/chatwidgetinput.cpp b/widgets/chatwidgetinput.cpp index 1141a2f64..eee866ece 100644 --- a/widgets/chatwidgetinput.cpp +++ b/widgets/chatwidgetinput.cpp @@ -52,7 +52,9 @@ ChatWidgetInput::ChatWidgetInput(ChatWidget *widget) this->edit.keyPressed.connect([this](QKeyEvent *event) { if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { - Channel *c = this->chatWidget->getChannel(); + auto ptr = this->chatWidget->getChannel(); + Channel *c = ptr.get(); + if (c != nullptr) { IrcManager::send("PRIVMSG #" + c->getName() + ": " + this->edit.toPlainText()); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index eb0fe5525..a910938a3 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -42,7 +42,7 @@ MainWindow::layoutVisibleChatWidgets(Channel *channel) for (auto it = widgets.begin(); it != widgets.end(); ++it) { ChatWidget *widget = *it; - if (channel == NULL || channel == widget->getChannel()) { + if (channel == NULL || channel == widget->getChannel().get()) { if (widget->getView().layoutMessages()) { widget->update(); } @@ -64,7 +64,7 @@ MainWindow::repaintVisibleChatWidgets(Channel *channel) for (auto it = widgets.begin(); it != widgets.end(); ++it) { ChatWidget *widget = *it; - if (channel == NULL || channel == widget->getChannel()) { + if (channel == NULL || channel == widget->getChannel().get()) { widget->getView().layoutMessages(); widget->update(); }