mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
refactored irc
This commit is contained in:
parent
12b30eb2ed
commit
b351c40d29
56 changed files with 1397 additions and 1154 deletions
336
chatterino.pro
336
chatterino.pro
|
@ -90,196 +90,204 @@ SOURCES += \
|
|||
src/application.cpp \
|
||||
src/channel.cpp \
|
||||
src/channeldata.cpp \
|
||||
src/singletons/ircmanager.cpp \
|
||||
src/messages/link.cpp \
|
||||
src/messages/message.cpp \
|
||||
src/widgets/notebook.cpp \
|
||||
src/widgets/helper/notebookbutton.cpp \
|
||||
src/widgets/helper/notebooktab.cpp \
|
||||
src/widgets/scrollbar.cpp \
|
||||
src/widgets/helper/scrollbarhighlight.cpp \
|
||||
src/widgets/settingsdialog.cpp \
|
||||
src/widgets/helper/settingsdialogtab.cpp \
|
||||
src/widgets/textinputdialog.cpp \
|
||||
src/singletons/loggingmanager.cpp \
|
||||
src/singletons/helper/loggingchannel.cpp \
|
||||
src/singletons/windowmanager.cpp \
|
||||
src/singletons/channelmanager.cpp \
|
||||
src/singletons/fontmanager.cpp \
|
||||
src/singletons/settingsmanager.cpp \
|
||||
src/singletons/emotemanager.cpp \
|
||||
src/messages/messagebuilder.cpp \
|
||||
src/twitch/twitchmessagebuilder.cpp \
|
||||
src/widgets/titlebar.cpp \
|
||||
src/singletons/accountmanager.cpp \
|
||||
src/twitch/twitchuser.cpp \
|
||||
src/ircaccount.cpp \
|
||||
src/widgets/accountpopup.cpp \
|
||||
src/widgets/basewidget.cpp \
|
||||
src/widgets/helper/resizingtextedit.cpp \
|
||||
src/singletons/completionmanager.cpp \
|
||||
src/widgets/logindialog.cpp \
|
||||
src/widgets/qualitypopup.cpp \
|
||||
src/widgets/emotepopup.cpp \
|
||||
src/widgets/helper/channelview.cpp \
|
||||
src/twitch/twitchchannel.cpp \
|
||||
src/widgets/helper/rippleeffectlabel.cpp \
|
||||
src/widgets/helper/rippleeffectbutton.cpp \
|
||||
src/messages/messagecolor.cpp \
|
||||
src/util/networkmanager.cpp \
|
||||
src/singletons/commandmanager.cpp \
|
||||
src/widgets/split.cpp \
|
||||
src/widgets/helper/splitinput.cpp \
|
||||
src/widgets/helper/splitheader.cpp \
|
||||
src/widgets/splitcontainer.cpp \
|
||||
src/widgets/helper/droppreview.cpp \
|
||||
src/widgets/window.cpp \
|
||||
src/widgets/helper/splitcolumn.cpp \
|
||||
src/widgets/accountswitchwidget.cpp \
|
||||
src/widgets/accountswitchpopupwidget.cpp \
|
||||
src/widgets/tooltipwidget.cpp \
|
||||
src/singletons/thememanager.cpp \
|
||||
src/twitch/twitchaccountmanager.cpp \
|
||||
src/singletons/helper/completionmodel.cpp \
|
||||
src/singletons/resourcemanager.cpp \
|
||||
src/singletons/helper/ircmessagehandler.cpp \
|
||||
src/singletons/pathmanager.cpp \
|
||||
src/widgets/helper/searchpopup.cpp \
|
||||
src/messages/messageelement.cpp \
|
||||
src/messages/image.cpp \
|
||||
src/messages/layouts/messagelayout.cpp \
|
||||
src/messages/layouts/messagelayoutelement.cpp \
|
||||
src/messages/layouts/messagelayoutcontainer.cpp \
|
||||
src/messages/layouts/messagelayoutelement.cpp \
|
||||
src/messages/link.cpp \
|
||||
src/messages/message.cpp \
|
||||
src/messages/messagebuilder.cpp \
|
||||
src/messages/messagecolor.cpp \
|
||||
src/messages/messageelement.cpp \
|
||||
src/providers/irc/abstractircserver.cpp \
|
||||
src/providers/twitch/ircmessagehandler.cpp \
|
||||
src/providers/twitch/twitchaccount.cpp \
|
||||
src/providers/twitch/twitchaccountmanager.cpp \
|
||||
src/providers/twitch/twitchchannel.cpp \
|
||||
src/providers/twitch/twitchmessagebuilder.cpp \
|
||||
src/providers/twitch/twitchserver.cpp \
|
||||
src/singletons/accountmanager.cpp \
|
||||
src/singletons/channelmanager.cpp \
|
||||
src/singletons/commandmanager.cpp \
|
||||
src/singletons/completionmanager.cpp \
|
||||
src/singletons/emotemanager.cpp \
|
||||
src/singletons/fontmanager.cpp \
|
||||
src/singletons/helper/completionmodel.cpp \
|
||||
src/singletons/helper/loggingchannel.cpp \
|
||||
src/singletons/helper/moderationaction.cpp \
|
||||
src/singletons/loggingmanager.cpp \
|
||||
src/singletons/pathmanager.cpp \
|
||||
src/singletons/resourcemanager.cpp \
|
||||
src/singletons/settingsmanager.cpp \
|
||||
src/singletons/thememanager.cpp \
|
||||
src/singletons/windowmanager.cpp \
|
||||
src/util/networkmanager.cpp \
|
||||
src/util/networkrequest.cpp \
|
||||
src/widgets/accountpopup.cpp \
|
||||
src/widgets/accountswitchpopupwidget.cpp \
|
||||
src/widgets/accountswitchwidget.cpp \
|
||||
src/widgets/basewidget.cpp \
|
||||
src/widgets/basewindow.cpp \
|
||||
src/widgets/emotepopup.cpp \
|
||||
src/widgets/helper/channelview.cpp \
|
||||
src/widgets/helper/droppreview.cpp \
|
||||
src/widgets/helper/label.cpp \
|
||||
src/widgets/helper/notebookbutton.cpp \
|
||||
src/widgets/helper/notebooktab.cpp \
|
||||
src/widgets/helper/resizingtextedit.cpp \
|
||||
src/widgets/helper/rippleeffectbutton.cpp \
|
||||
src/widgets/helper/rippleeffectlabel.cpp \
|
||||
src/widgets/helper/scrollbarhighlight.cpp \
|
||||
src/widgets/helper/searchpopup.cpp \
|
||||
src/widgets/helper/settingsdialogtab.cpp \
|
||||
src/widgets/helper/splitcolumn.cpp \
|
||||
src/widgets/helper/splitheader.cpp \
|
||||
src/widgets/helper/splitinput.cpp \
|
||||
src/widgets/helper/titlebarbutton.cpp \
|
||||
src/widgets/logindialog.cpp \
|
||||
src/widgets/notebook.cpp \
|
||||
src/widgets/qualitypopup.cpp \
|
||||
src/widgets/scrollbar.cpp \
|
||||
src/widgets/settingsdialog.cpp \
|
||||
src/widgets/settingspages/aboutpage.cpp \
|
||||
src/widgets/settingspages/accountspage.cpp \
|
||||
src/widgets/settingspages/appearancepage.cpp \
|
||||
src/widgets/settingspages/settingspage.cpp \
|
||||
src/widgets/settingspages/behaviourpage.cpp \
|
||||
src/widgets/settingspages/commandpage.cpp \
|
||||
src/widgets/settingspages/emotespage.cpp \
|
||||
src/widgets/settingspages/highlightingpage.cpp \
|
||||
src/widgets/settingspages/accountspage.cpp \
|
||||
src/widgets/settingspages/aboutpage.cpp \
|
||||
src/widgets/settingspages/moderationpage.cpp \
|
||||
src/widgets/settingspages/logspage.cpp \
|
||||
src/widgets/basewindow.cpp \
|
||||
src/singletons/helper/moderationaction.cpp \
|
||||
src/widgets/streamview.cpp \
|
||||
src/util/networkrequest.cpp \
|
||||
src/widgets/settingspages/ignoreuserspage.cpp \
|
||||
src/widgets/settingspages/ignoremessagespage.cpp \
|
||||
src/widgets/settingspages/specialchannelspage.cpp \
|
||||
src/widgets/settingspages/ignoreuserspage.cpp \
|
||||
src/widgets/settingspages/keyboardsettingspage.cpp \
|
||||
src/widgets/helper/titlebarbutton.cpp \
|
||||
src/widgets/helper/label.cpp
|
||||
src/widgets/settingspages/logspage.cpp \
|
||||
src/widgets/settingspages/moderationpage.cpp \
|
||||
src/widgets/settingspages/settingspage.cpp \
|
||||
src/widgets/settingspages/specialchannelspage.cpp \
|
||||
src/widgets/split.cpp \
|
||||
src/widgets/splitcontainer.cpp \
|
||||
src/widgets/streamview.cpp \
|
||||
src/widgets/textinputdialog.cpp \
|
||||
src/widgets/titlebar.cpp \
|
||||
src/widgets/tooltipwidget.cpp \
|
||||
src/widgets/window.cpp \
|
||||
src/providers/irc/_ircaccount.cpp \
|
||||
src/providers/irc/_ircserver.cpp \
|
||||
src/providers/irc/_ircchannel.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/precompiled_header.hpp \
|
||||
src/util/posttothread.hpp \
|
||||
src/channel.hpp \
|
||||
src/util/concurrentmap.hpp \
|
||||
src/emojis.hpp \
|
||||
src/singletons/ircmanager.hpp \
|
||||
src/messages/link.hpp \
|
||||
src/messages/message.hpp \
|
||||
src/twitch/emotevalue.hpp \
|
||||
src/widgets/notebook.hpp \
|
||||
src/widgets/helper/notebookbutton.hpp \
|
||||
src/widgets/helper/notebooktab.hpp \
|
||||
src/widgets/scrollbar.hpp \
|
||||
src/widgets/helper/scrollbarhighlight.hpp \
|
||||
src/widgets/settingsdialog.hpp \
|
||||
src/widgets/helper/settingsdialogtab.hpp \
|
||||
src/widgets/helper/signallabel.hpp \
|
||||
src/widgets/textinputdialog.hpp \
|
||||
src/widgets/helper/resizingtextedit.hpp \
|
||||
src/messages/limitedqueue.hpp \
|
||||
src/messages/limitedqueuesnapshot.hpp \
|
||||
src/singletons/loggingmanager.hpp \
|
||||
src/singletons/helper/loggingchannel.hpp \
|
||||
src/singletons/channelmanager.hpp \
|
||||
src/singletons/windowmanager.hpp \
|
||||
src/singletons/settingsmanager.hpp \
|
||||
src/singletons/fontmanager.hpp \
|
||||
src/singletons/emotemanager.hpp \
|
||||
src/util/urlfetch.hpp \
|
||||
src/messages/messageparseargs.hpp \
|
||||
src/messages/messagebuilder.hpp \
|
||||
src/twitch/twitchmessagebuilder.hpp \
|
||||
src/widgets/titlebar.hpp \
|
||||
src/singletons/accountmanager.hpp \
|
||||
src/twitch/twitchuser.hpp \
|
||||
src/ircaccount.hpp \
|
||||
src/widgets/accountpopup.hpp \
|
||||
src/util/distancebetweenpoints.hpp \
|
||||
src/widgets/basewidget.hpp \
|
||||
src/singletons/completionmanager.hpp \
|
||||
src/widgets/helper/channelview.hpp \
|
||||
src/twitch/twitchchannel.hpp \
|
||||
src/widgets/helper/rippleeffectbutton.hpp \
|
||||
src/widgets/helper/rippleeffectlabel.hpp \
|
||||
src/widgets/qualitypopup.hpp \
|
||||
src/widgets/emotepopup.hpp \
|
||||
src/messages/messagecolor.hpp \
|
||||
src/util/nativeeventhelper.hpp \
|
||||
src/debug/log.hpp \
|
||||
src/util/benchmark.hpp \
|
||||
src/util/networkmanager.hpp \
|
||||
src/singletons/commandmanager.hpp \
|
||||
src/widgets/split.hpp \
|
||||
src/widgets/helper/splitheader.hpp \
|
||||
src/widgets/helper/splitinput.hpp \
|
||||
src/widgets/window.hpp \
|
||||
src/widgets/splitcontainer.hpp \
|
||||
src/widgets/helper/droppreview.hpp \
|
||||
src/widgets/helper/splitcolumn.hpp \
|
||||
src/util/irchelpers.hpp \
|
||||
src/util/helpers.hpp \
|
||||
src/widgets/accountswitchwidget.hpp \
|
||||
src/widgets/accountswitchpopupwidget.hpp \
|
||||
src/const.hpp \
|
||||
src/widgets/tooltipwidget.hpp \
|
||||
src/singletons/thememanager.hpp \
|
||||
src/twitch/twitchaccountmanager.hpp \
|
||||
src/singletons/helper/completionmodel.hpp \
|
||||
src/singletons/helper/chatterinosetting.hpp \
|
||||
src/singletons/resourcemanager.hpp \
|
||||
src/util/emotemap.hpp \
|
||||
src/singletons/helper/ircmessagehandler.hpp \
|
||||
src/util/serialize-custom.hpp \
|
||||
src/debug/log.hpp \
|
||||
src/emojis.hpp \
|
||||
src/messages/highlightphrase.hpp \
|
||||
src/messages/selection.hpp \
|
||||
src/singletons/pathmanager.hpp \
|
||||
src/widgets/helper/searchpopup.hpp \
|
||||
src/widgets/helper/shortcut.hpp \
|
||||
src/messages/messageelement.hpp \
|
||||
src/messages/image.hpp \
|
||||
src/messages/layouts/messagelayout.hpp \
|
||||
src/messages/layouts/messagelayoutelement.hpp \
|
||||
src/messages/layouts/messagelayoutcontainer.hpp \
|
||||
src/util/property.hpp \
|
||||
src/widgets/settingspages/appearancepage.hpp \
|
||||
src/widgets/settingspages/settingspage.hpp \
|
||||
src/messages/layouts/messagelayoutelement.hpp \
|
||||
src/messages/limitedqueue.hpp \
|
||||
src/messages/limitedqueuesnapshot.hpp \
|
||||
src/messages/link.hpp \
|
||||
src/messages/message.hpp \
|
||||
src/messages/messagebuilder.hpp \
|
||||
src/messages/messagecolor.hpp \
|
||||
src/messages/messageelement.hpp \
|
||||
src/messages/messageparseargs.hpp \
|
||||
src/messages/selection.hpp \
|
||||
src/providers/twitch/emotevalue.hpp \
|
||||
src/providers/twitch/ircmessagehandler.hpp \
|
||||
src/providers/twitch/twitchaccount.hpp \
|
||||
src/providers/twitch/twitchaccountmanager.hpp \
|
||||
src/providers/twitch/twitchchannel.hpp \
|
||||
src/providers/twitch/twitchmessagebuilder.hpp \
|
||||
src/providers/twitch/twitchserver.hpp \
|
||||
src/singletons/accountmanager.hpp \
|
||||
src/singletons/channelmanager.hpp \
|
||||
src/singletons/commandmanager.hpp \
|
||||
src/singletons/completionmanager.hpp \
|
||||
src/singletons/emotemanager.hpp \
|
||||
src/singletons/fontmanager.hpp \
|
||||
src/singletons/helper/chatterinosetting.hpp \
|
||||
src/singletons/helper/completionmodel.hpp \
|
||||
src/singletons/helper/loggingchannel.hpp \
|
||||
src/singletons/helper/moderationaction.hpp \
|
||||
src/singletons/loggingmanager.hpp \
|
||||
src/singletons/pathmanager.hpp \
|
||||
src/singletons/providermanager.hp \
|
||||
src/singletons/resourcemanager.hpp \
|
||||
src/singletons/settingsmanager.hpp \
|
||||
src/singletons/thememanager.hpp \
|
||||
src/singletons/windowmanager.hpp \
|
||||
src/util/benchmark.hpp \
|
||||
src/util/concurrentmap.hpp \
|
||||
src/util/distancebetweenpoints.hpp \
|
||||
src/util/emotemap.hpp \
|
||||
src/util/flagsenum.hpp \
|
||||
src/util/helpers.hpp \
|
||||
src/util/irchelpers.hpp \
|
||||
src/util/layoutcreator.hpp \
|
||||
src/util/nativeeventhelper.hpp \
|
||||
src/util/networkmanager.hpp \
|
||||
src/util/networkrequest.hpp \
|
||||
src/util/networkrequester.hpp \
|
||||
src/util/networkworker.hpp \
|
||||
src/util/posttothread.hpp \
|
||||
src/util/property.hpp \
|
||||
src/util/serialize-custom.hpp \
|
||||
src/util/urlfetch.hpp \
|
||||
src/widgets/accountpopup.hpp \
|
||||
src/widgets/accountswitchpopupwidget.hpp \
|
||||
src/widgets/accountswitchwidget.hpp \
|
||||
src/widgets/basewidget.hpp \
|
||||
src/widgets/basewindow.hpp \
|
||||
src/widgets/emotepopup.hpp \
|
||||
src/widgets/helper/channelview.hpp \
|
||||
src/widgets/helper/droppreview.hpp \
|
||||
src/widgets/helper/label.hpp \
|
||||
src/widgets/helper/notebookbutton.hpp \
|
||||
src/widgets/helper/notebooktab.hpp \
|
||||
src/widgets/helper/resizingtextedit.hpp \
|
||||
src/widgets/helper/rippleeffectbutton.hpp \
|
||||
src/widgets/helper/rippleeffectlabel.hpp \
|
||||
src/widgets/helper/scrollbarhighlight.hpp \
|
||||
src/widgets/helper/searchpopup.hpp \
|
||||
src/widgets/helper/settingsdialogtab.hpp \
|
||||
src/widgets/helper/shortcut.hpp \
|
||||
src/widgets/helper/signallabel.hpp \
|
||||
src/widgets/helper/splitcolumn.hpp \
|
||||
src/widgets/helper/splitheader.hpp \
|
||||
src/widgets/helper/splitinput.hpp \
|
||||
src/widgets/helper/titlebarbutton.hpp \
|
||||
src/widgets/notebook.hpp \
|
||||
src/widgets/qualitypopup.hpp \
|
||||
src/widgets/scrollbar.hpp \
|
||||
src/widgets/settingsdialog.hpp \
|
||||
src/widgets/settingspages/aboutpage.hpp \
|
||||
src/widgets/settingspages/accountspage.hpp \
|
||||
src/widgets/settingspages/appearancepage.hpp \
|
||||
src/widgets/settingspages/behaviourpage.hpp \
|
||||
src/widgets/settingspages/commandpage.hpp \
|
||||
src/widgets/settingspages/emotespage.hpp \
|
||||
src/widgets/settingspages/highlightingpage.hpp \
|
||||
src/widgets/settingspages/accountspage.hpp \
|
||||
src/widgets/settingspages/aboutpage.hpp \
|
||||
src/widgets/settingspages/moderationpage.hpp \
|
||||
src/widgets/settingspages/logspage.hpp \
|
||||
src/widgets/basewindow.hpp \
|
||||
src/singletons/helper/moderationaction.hpp \
|
||||
src/widgets/streamview.hpp \
|
||||
src/util/networkrequest.hpp \
|
||||
src/util/networkworker.hpp \
|
||||
src/util/networkrequester.hpp \
|
||||
src/widgets/settingspages/ignoreuserspage.hpp \
|
||||
src/widgets/settingspages/ignoremessagespage.hpp \
|
||||
src/widgets/settingspages/specialchannelspage.hpp \
|
||||
src/widgets/settingspages/ignoreuserspage.hpp \
|
||||
src/widgets/settingspages/keyboardsettingspage.hpp \
|
||||
src/widgets/helper/titlebarbutton.hpp \
|
||||
src/widgets/helper/label.hpp \
|
||||
src/util/flagsenum.hpp
|
||||
src/widgets/settingspages/logspage.hpp \
|
||||
src/widgets/settingspages/moderationpage.hpp \
|
||||
src/widgets/settingspages/settingspage.hpp \
|
||||
src/widgets/settingspages/specialchannelspage.hpp \
|
||||
src/widgets/split.hpp \
|
||||
src/widgets/splitcontainer.hpp \
|
||||
src/widgets/streamview.hpp \
|
||||
src/widgets/textinputdialog.hpp \
|
||||
src/widgets/titlebar.hpp \
|
||||
src/widgets/tooltipwidget.hpp \
|
||||
src/widgets/window.hpp \
|
||||
src/common.hpp \
|
||||
src/providers/irc/_ircchannel.hpp \
|
||||
src/providers/irc/_ircaccount.hpp \
|
||||
src/providers/irc/_ircserver.hpp \
|
||||
src/providers/irc/abstractircserver.hpp
|
||||
|
||||
RESOURCES += \
|
||||
resources/resources.qrc
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "application.hpp"
|
||||
#include "singletons/loggingmanager.hpp"
|
||||
#include "providers/twitch/twitchserver.hpp"
|
||||
#include "singletons/accountmanager.hpp"
|
||||
#include "singletons/commandmanager.hpp"
|
||||
#include "singletons/emotemanager.hpp"
|
||||
#include "singletons/loggingmanager.hpp"
|
||||
#include "singletons/settingsmanager.hpp"
|
||||
#include "singletons/thememanager.hpp"
|
||||
#include "singletons/windowmanager.hpp"
|
||||
|
@ -42,7 +43,7 @@ Application::~Application()
|
|||
int Application::run(QApplication &qtApp)
|
||||
{
|
||||
// Start connecting to the IRC Servers (Twitch only for now)
|
||||
singletons::IrcManager::getInstance().connect();
|
||||
providers::twitch::TwitchServer::getInstance().connect();
|
||||
|
||||
// Show main window
|
||||
singletons::WindowManager::getInstance().getMainWindow().show();
|
||||
|
|
|
@ -23,9 +23,14 @@ Channel::Channel(const QString &_name)
|
|||
{
|
||||
}
|
||||
|
||||
Channel::~Channel()
|
||||
{
|
||||
this->destroyed.invoke();
|
||||
}
|
||||
|
||||
bool Channel::isEmpty() const
|
||||
{
|
||||
return false;
|
||||
return this->name.isEmpty();
|
||||
}
|
||||
|
||||
messages::LimitedQueueSnapshot<messages::MessagePtr> Channel::getMessageSnapshot()
|
||||
|
@ -103,4 +108,13 @@ void Channel::sendMessage(const QString &message)
|
|||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> Channel::getEmpty()
|
||||
{
|
||||
static std::shared_ptr<Channel> channel(new Channel(""));
|
||||
return channel;
|
||||
}
|
||||
|
||||
void Channel::onConnected()
|
||||
{
|
||||
}
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -23,11 +23,15 @@ class Channel : public std::enable_shared_from_this<Channel>
|
|||
{
|
||||
public:
|
||||
explicit Channel(const QString &_name);
|
||||
virtual ~Channel();
|
||||
|
||||
pajlada::Signals::Signal<const QString &, const QString &> sendMessageSignal;
|
||||
|
||||
boost::signals2::signal<void(messages::MessagePtr &)> messageRemovedFromStart;
|
||||
boost::signals2::signal<void(messages::MessagePtr &)> messageAppended;
|
||||
boost::signals2::signal<void(std::vector<messages::MessagePtr> &)> messagesAddedAtStart;
|
||||
boost::signals2::signal<void(size_t index, messages::MessagePtr &)> messageReplaced;
|
||||
pajlada::Signals::NoArgSignal destroyed;
|
||||
|
||||
virtual bool isEmpty() const;
|
||||
messages::LimitedQueueSnapshot<messages::MessagePtr> getMessageSnapshot();
|
||||
|
@ -58,6 +62,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
static std::shared_ptr<Channel> getEmpty();
|
||||
|
||||
protected:
|
||||
virtual void onConnected();
|
||||
|
||||
private:
|
||||
messages::LimitedQueue<messages::MessagePtr> messages;
|
||||
};
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "debug/log.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
enum class HighlightState {
|
||||
|
|
|
@ -6,10 +6,11 @@ namespace chatterino {
|
|||
|
||||
static const QString ANONYMOUS_USERNAME_LABEL(" - anonymous - ");
|
||||
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
static const QString ANONYMOUS_USERNAME("justinfan64537");
|
||||
|
||||
} // namespace twitch
|
||||
}
|
||||
} // namespace providers
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#include "ircaccount.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
IrcUser2::IrcUser2(const QString &_userName, const QString &_nickName, const QString &_realName,
|
||||
const QString &_password)
|
||||
: userName(_userName)
|
||||
, nickName(_nickName)
|
||||
, realName(_realName)
|
||||
, password(_password)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &IrcUser2::getUserName() const
|
||||
{
|
||||
return this->userName;
|
||||
}
|
||||
|
||||
const QString &IrcUser2::getNickName() const
|
||||
{
|
||||
return this->nickName;
|
||||
}
|
||||
|
||||
const QString &IrcUser2::getRealName() const
|
||||
{
|
||||
return this->realName;
|
||||
}
|
||||
|
||||
const QString &IrcUser2::getPassword() const
|
||||
{
|
||||
return this->password;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class IrcUser2
|
||||
{
|
||||
public:
|
||||
IrcUser2(const QString &userName, const QString &nickName, const QString &realName,
|
||||
const QString &password);
|
||||
|
||||
const QString &getUserName() const;
|
||||
const QString &getNickName() const;
|
||||
const QString &getRealName() const;
|
||||
const QString &getPassword() const;
|
||||
|
||||
private:
|
||||
QString userName;
|
||||
QString nickName;
|
||||
QString realName;
|
||||
QString password;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
|
@ -87,7 +87,8 @@ void Image::loadImage()
|
|||
|
||||
singletons::EmoteManager::getInstance().incGeneration();
|
||||
|
||||
postToThread([] { singletons::WindowManager::getInstance().layoutVisibleChatWidgets(); });
|
||||
util::postToThread(
|
||||
[] { singletons::WindowManager::getInstance().layoutVisibleChatWidgets(); });
|
||||
});
|
||||
|
||||
singletons::EmoteManager::getInstance().getGifUpdateSignal().connect([=]() {
|
||||
|
|
|
@ -20,8 +20,7 @@ class Image;
|
|||
|
||||
namespace layouts {
|
||||
|
||||
struct MessageLayoutElement : boost::noncopyable
|
||||
{
|
||||
struct MessageLayoutElement : boost::noncopyable {
|
||||
public:
|
||||
MessageLayoutElement(MessageElement &creator, const QSize &size);
|
||||
|
||||
|
@ -47,7 +46,6 @@ protected:
|
|||
private:
|
||||
QRect rect;
|
||||
Link link;
|
||||
// bool isInNewLine;
|
||||
MessageElement &creator;
|
||||
};
|
||||
|
||||
|
|
37
src/providers/irc/_ircaccount.cpp
Normal file
37
src/providers/irc/_ircaccount.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "_ircaccount.hpp"
|
||||
|
||||
// namespace chatterino {
|
||||
// namespace providers {
|
||||
// namespace irc {
|
||||
// IrcAccount::IrcAccount(const QString &_userName, const QString &_nickName, const QString
|
||||
// &_realName,
|
||||
// const QString &_password)
|
||||
// : userName(_userName)
|
||||
// , nickName(_nickName)
|
||||
// , realName(_realName)
|
||||
// , password(_password)
|
||||
//{
|
||||
//}
|
||||
|
||||
// const QString &IrcAccount::getUserName() const
|
||||
//{
|
||||
// return this->userName;
|
||||
//}
|
||||
|
||||
// const QString &IrcAccount::getNickName() const
|
||||
//{
|
||||
// return this->nickName;
|
||||
//}
|
||||
|
||||
// const QString &IrcAccount::getRealName() const
|
||||
//{
|
||||
// return this->realName;
|
||||
//}
|
||||
|
||||
// const QString &IrcAccount::getPassword() const
|
||||
//{
|
||||
// return this->password;
|
||||
//}
|
||||
//} // namespace irc
|
||||
//} // namespace providers
|
||||
//} // namespace chatterino
|
27
src/providers/irc/_ircaccount.hpp
Normal file
27
src/providers/irc/_ircaccount.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
// namespace chatterino {
|
||||
// namespace providers {
|
||||
// namespace irc {
|
||||
// class IrcAccount
|
||||
//{
|
||||
// public:
|
||||
// IrcAccount(const QString &userName, const QString &nickName, const QString &realName,
|
||||
// const QString &password);
|
||||
|
||||
// const QString &getUserName() const;
|
||||
// const QString &getNickName() const;
|
||||
// const QString &getRealName() const;
|
||||
// const QString &getPassword() const;
|
||||
|
||||
// private:
|
||||
// QString userName;
|
||||
// QString nickName;
|
||||
// QString realName;
|
||||
// QString password;
|
||||
//};
|
||||
//} // namespace irc
|
||||
//} // namespace providers
|
||||
//} // namespace chatterino
|
11
src/providers/irc/_ircchannel.cpp
Normal file
11
src/providers/irc/_ircchannel.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "_ircchannel.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace irc {
|
||||
// IrcChannel::IrcChannel()
|
||||
//{
|
||||
//}
|
||||
} // namespace irc
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
13
src/providers/irc/_ircchannel.hpp
Normal file
13
src/providers/irc/_ircchannel.hpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace irc {
|
||||
// class IrcChannel
|
||||
//{
|
||||
// public:
|
||||
// IrcChannel();
|
||||
//};
|
||||
} // namespace irc
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
14
src/providers/irc/_ircserver.cpp
Normal file
14
src/providers/irc/_ircserver.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include "_ircserver.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace irc {
|
||||
// IrcServer::IrcServer(const QString &hostname, int port)
|
||||
//{
|
||||
// this->initConnection();
|
||||
//}
|
||||
} // namespace irc
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
25
src/providers/irc/_ircserver.hpp
Normal file
25
src/providers/irc/_ircserver.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "providers/irc/_ircaccount.hpp"
|
||||
#include "providers/irc/abstractircserver.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace irc {
|
||||
// class IrcServer
|
||||
//{
|
||||
// public:
|
||||
// IrcServer(const QString &hostname, int port);
|
||||
|
||||
// void setAccount(std::shared_ptr<IrcAccount> newAccount);
|
||||
// std::shared_ptr<IrcAccount> getAccount() const;
|
||||
|
||||
// protected:
|
||||
// virtual void initializeConnection(Communi::IrcConnection *connection, bool isReadConnection);
|
||||
|
||||
// virtual void privateMessageReceived(Communi::IrcPrivateMessage *message);
|
||||
// virtual void messageReceived(Communi::IrcMessage *message);
|
||||
//};
|
||||
} // namespace irc
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
226
src/providers/irc/abstractircserver.cpp
Normal file
226
src/providers/irc/abstractircserver.cpp
Normal file
|
@ -0,0 +1,226 @@
|
|||
#include "abstractircserver.hpp"
|
||||
|
||||
#include "common.hpp"
|
||||
#include "messages/limitedqueuesnapshot.hpp"
|
||||
#include "messages/message.hpp"
|
||||
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace irc {
|
||||
|
||||
AbstractIrcServer::AbstractIrcServer()
|
||||
{
|
||||
// Initialize the connections
|
||||
this->writeConnection.reset(new Communi::IrcConnection);
|
||||
this->writeConnection->moveToThread(QCoreApplication::instance()->thread());
|
||||
|
||||
QObject::connect(this->writeConnection.get(), &Communi::IrcConnection::messageReceived,
|
||||
[this](auto msg) { this->writeConnectionMessageReceived(msg); });
|
||||
|
||||
// Listen to read connection message signals
|
||||
this->readConnection.reset(new Communi::IrcConnection);
|
||||
this->readConnection->moveToThread(QCoreApplication::instance()->thread());
|
||||
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::messageReceived,
|
||||
[this](auto msg) { this->messageReceived(msg); });
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::privateMessageReceived,
|
||||
[this](auto msg) { this->privateMessageReceived(msg); });
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::connected,
|
||||
[this] { this->onConnected(); });
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::disconnected,
|
||||
[this] { this->onDisconnected(); });
|
||||
}
|
||||
|
||||
Communi::IrcConnection *AbstractIrcServer::getReadConnection() const
|
||||
{
|
||||
return this->readConnection.get();
|
||||
}
|
||||
|
||||
void AbstractIrcServer::connect()
|
||||
{
|
||||
this->disconnect();
|
||||
|
||||
// if (this->hasSeperateWriteConnection()) {
|
||||
this->initializeConnection(this->writeConnection.get(), false, true);
|
||||
this->initializeConnection(this->readConnection.get(), true, false);
|
||||
// } else {
|
||||
// this->initializeConnection(this->readConnection.get(), true, true);
|
||||
// }
|
||||
|
||||
// fourtf: this should be asynchronous
|
||||
{
|
||||
std::lock_guard<std::mutex> lock1(this->connectionMutex);
|
||||
std::lock_guard<std::mutex> lock2(this->channelMutex);
|
||||
|
||||
for (std::weak_ptr<Channel> &weak : this->channels.values()) {
|
||||
std::shared_ptr<Channel> chan = weak.lock();
|
||||
if (!chan) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this->writeConnection->sendRaw("JOIN #" + chan->name);
|
||||
this->readConnection->sendRaw("JOIN #" + chan->name);
|
||||
}
|
||||
|
||||
this->writeConnection->open();
|
||||
this->readConnection->open();
|
||||
}
|
||||
|
||||
this->onConnected();
|
||||
this->connected.invoke();
|
||||
}
|
||||
|
||||
void AbstractIrcServer::disconnect()
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(this->connectionMutex);
|
||||
|
||||
this->readConnection->close();
|
||||
this->writeConnection->close();
|
||||
}
|
||||
|
||||
void AbstractIrcServer::sendMessage(const QString &channelName, const QString &message)
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(this->connectionMutex);
|
||||
|
||||
// fourtf: trim the message if it's sent from twitch chat
|
||||
|
||||
if (this->writeConnection) {
|
||||
this->writeConnection->sendRaw("PRIVMSG #" + channelName + " :" + message);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractIrcServer::writeConnectionMessageReceived(Communi::IrcMessage *message)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> AbstractIrcServer::addChannel(const QString &channelName)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||
|
||||
// value exists
|
||||
auto it = this->channels.find(channelName);
|
||||
if (it != this->channels.end()) {
|
||||
std::shared_ptr<Channel> chan = it.value().lock();
|
||||
|
||||
if (chan) {
|
||||
return chan;
|
||||
}
|
||||
}
|
||||
|
||||
// value doesn't exist
|
||||
std::shared_ptr<Channel> chan = this->createChannel(channelName);
|
||||
if (!chan) {
|
||||
return Channel::getEmpty();
|
||||
}
|
||||
|
||||
QString clojuresInCppAreShit = channelName;
|
||||
|
||||
this->channels.insert(channelName, chan);
|
||||
chan->destroyed.connect([this, clojuresInCppAreShit] {
|
||||
// fourtf: issues when the server itself in destroyed
|
||||
|
||||
debug::Log("[AbstractIrcServer::addChannel] {} was destroyed", clojuresInCppAreShit);
|
||||
this->channels.remove(clojuresInCppAreShit);
|
||||
});
|
||||
|
||||
// join irc channel
|
||||
{
|
||||
std::lock_guard<std::mutex> lock2(this->connectionMutex);
|
||||
if (this->readConnection) {
|
||||
this->readConnection->sendRaw("JOIN #" + channelName);
|
||||
}
|
||||
|
||||
if (this->writeConnection) {
|
||||
this->writeConnection->sendRaw("JOIN #" + channelName);
|
||||
}
|
||||
}
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> AbstractIrcServer::getChannel(const QString &channelName)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||
|
||||
// value exists
|
||||
auto it = this->channels.find(channelName);
|
||||
if (it != this->channels.end()) {
|
||||
std::shared_ptr<Channel> chan = it.value().lock();
|
||||
|
||||
if (chan) {
|
||||
return chan;
|
||||
}
|
||||
}
|
||||
|
||||
return Channel::getEmpty();
|
||||
}
|
||||
|
||||
void AbstractIrcServer::onConnected()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||
|
||||
MessagePtr connMsg = Message::createSystemMessage("connected to chat");
|
||||
MessagePtr reconnMsg = Message::createSystemMessage("reconnected to chat");
|
||||
|
||||
for (std::weak_ptr<Channel> &weak : this->channels.values()) {
|
||||
std::shared_ptr<Channel> chan = weak.lock();
|
||||
if (!chan) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LimitedQueueSnapshot<MessagePtr> snapshot = chan->getMessageSnapshot();
|
||||
|
||||
bool replaceMessage =
|
||||
snapshot.getLength() > 0 &&
|
||||
snapshot[snapshot.getLength() - 1]->flags & Message::DisconnectedMessage;
|
||||
|
||||
if (replaceMessage) {
|
||||
chan->replaceMessage(snapshot[snapshot.getLength() - 1], reconnMsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
chan->addMessage(connMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractIrcServer::onDisconnected()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||
|
||||
MessagePtr msg = Message::createSystemMessage("disconnected from chat");
|
||||
msg->flags &= Message::DisconnectedMessage;
|
||||
|
||||
for (std::weak_ptr<Channel> &weak : this->channels.values()) {
|
||||
std::shared_ptr<Channel> chan = weak.lock();
|
||||
if (!chan) {
|
||||
continue;
|
||||
}
|
||||
|
||||
chan->addMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> AbstractIrcServer::getCustomChannel(const QString &channelName)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AbstractIrcServer::addFakeMessage(const QString &data)
|
||||
{
|
||||
auto fakeMessage = Communi::IrcMessage::fromData(data.toUtf8(), this->readConnection.get());
|
||||
|
||||
this->privateMessageReceived(qobject_cast<Communi::IrcPrivateMessage *>(fakeMessage));
|
||||
}
|
||||
|
||||
void AbstractIrcServer::privateMessageReceived(Communi::IrcPrivateMessage *message)
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractIrcServer::messageReceived(Communi::IrcMessage *message)
|
||||
{
|
||||
}
|
||||
} // namespace irc
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
63
src/providers/irc/abstractircserver.hpp
Normal file
63
src/providers/irc/abstractircserver.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <IrcMessage>
|
||||
#include <mutex>
|
||||
#include <pajlada/signals/signal.hpp>
|
||||
|
||||
#include "channel.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace irc {
|
||||
class AbstractIrcServer
|
||||
{
|
||||
public:
|
||||
// connection
|
||||
Communi::IrcConnection *getReadConnection() const;
|
||||
|
||||
void connect();
|
||||
void disconnect();
|
||||
|
||||
void sendMessage(const QString &channelName, const QString &message);
|
||||
|
||||
// channels
|
||||
std::shared_ptr<Channel> addChannel(const QString &channelName);
|
||||
std::shared_ptr<Channel> getChannel(const QString &channelName);
|
||||
|
||||
// signals
|
||||
pajlada::Signals::NoArgSignal connected;
|
||||
pajlada::Signals::NoArgSignal disconnected;
|
||||
pajlada::Signals::Signal<Communi::IrcPrivateMessage *> onPrivateMessage;
|
||||
|
||||
void addFakeMessage(const QString &data);
|
||||
|
||||
protected:
|
||||
AbstractIrcServer();
|
||||
|
||||
virtual void initializeConnection(Communi::IrcConnection *connection, bool isRead,
|
||||
bool isWrite) = 0;
|
||||
virtual std::shared_ptr<Channel> createChannel(const QString &channelName) = 0;
|
||||
|
||||
virtual void privateMessageReceived(Communi::IrcPrivateMessage *message);
|
||||
virtual void messageReceived(Communi::IrcMessage *message);
|
||||
virtual void writeConnectionMessageReceived(Communi::IrcMessage *message);
|
||||
|
||||
virtual void onConnected();
|
||||
virtual void onDisconnected();
|
||||
|
||||
virtual std::shared_ptr<Channel> getCustomChannel(const QString &channelName);
|
||||
|
||||
private:
|
||||
void initConnection();
|
||||
|
||||
QMap<QString, std::weak_ptr<Channel>> channels;
|
||||
|
||||
std::unique_ptr<Communi::IrcConnection> writeConnection = nullptr;
|
||||
std::unique_ptr<Communi::IrcConnection> readConnection = nullptr;
|
||||
|
||||
std::mutex connectionMutex;
|
||||
std::mutex channelMutex;
|
||||
};
|
||||
} // namespace irc
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -3,6 +3,7 @@
|
|||
#include "QString"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
struct EmoteValue {
|
||||
|
@ -29,4 +30,5 @@ private:
|
|||
};
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -5,73 +5,83 @@
|
|||
#include "debug/log.hpp"
|
||||
#include "messages/limitedqueue.hpp"
|
||||
#include "messages/message.hpp"
|
||||
#include "singletons/channelmanager.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
//#include "singletons/channelmanager.hpp"
|
||||
#include "singletons/resourcemanager.hpp"
|
||||
#include "singletons/windowmanager.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "twitchserver.hpp"
|
||||
|
||||
using namespace chatterino::singletons;
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
namespace helper {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
IrcMessageHandler::IrcMessageHandler(ChannelManager &_channelManager,
|
||||
ResourceManager &_resourceManager)
|
||||
: channelManager(_channelManager)
|
||||
, resourceManager(_resourceManager)
|
||||
IrcMessageHandler::IrcMessageHandler(singletons::ResourceManager &_resourceManager)
|
||||
: resourceManager(_resourceManager)
|
||||
{
|
||||
}
|
||||
|
||||
IrcMessageHandler &IrcMessageHandler::getInstance()
|
||||
{
|
||||
static IrcMessageHandler instance(ChannelManager::getInstance(),
|
||||
ResourceManager::getInstance());
|
||||
static IrcMessageHandler instance(singletons::ResourceManager::getInstance());
|
||||
return instance;
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleRoomStateMessage(Communi::IrcMessage *message)
|
||||
{
|
||||
const auto &tags = message->tags();
|
||||
|
||||
auto iterator = tags.find("room-id");
|
||||
|
||||
if (iterator != tags.end()) {
|
||||
auto roomID = iterator.value().toString();
|
||||
|
||||
auto channel =
|
||||
this->channelManager.getTwitchChannel(QString(message->toData()).split("#").at(1));
|
||||
auto twitchChannel = dynamic_cast<twitch::TwitchChannel *>(channel.get());
|
||||
if (twitchChannel != nullptr) {
|
||||
QStringList words = QString(message->toData()).split("#");
|
||||
|
||||
// ensure the format is valid
|
||||
if (words.length() < 2)
|
||||
return;
|
||||
|
||||
QString channelName = words.at(1);
|
||||
|
||||
auto channel = TwitchServer::getInstance().getChannel(channelName);
|
||||
|
||||
if (auto twitchChannel = dynamic_cast<twitch::TwitchChannel *>(channel.get())) {
|
||||
// set the room id of the channel
|
||||
twitchChannel->setRoomID(roomID);
|
||||
}
|
||||
|
||||
this->resourceManager.loadChannelData(roomID);
|
||||
ResourceManager::getInstance().loadChannelData(roomID);
|
||||
}
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
||||
{
|
||||
assert(message->parameters().length() >= 1);
|
||||
// check parameter count
|
||||
if (message->parameters().length() < 1)
|
||||
return;
|
||||
|
||||
auto rawChannelName = message->parameter(0);
|
||||
QString chanName = message->parameter(0);
|
||||
|
||||
assert(rawChannelName.length() >= 2);
|
||||
// check channel name length
|
||||
if (chanName.length() >= 2)
|
||||
return;
|
||||
|
||||
auto trimmedChannelName = rawChannelName.mid(1);
|
||||
chanName = chanName.mid(1);
|
||||
|
||||
auto c = this->channelManager.getTwitchChannel(trimmedChannelName);
|
||||
// get channel
|
||||
auto chan = TwitchServer::getInstance().getChannel(chanName);
|
||||
|
||||
if (!c) {
|
||||
debug::Log(
|
||||
"[IrcMessageHandler:handleClearChatMessage] Channel {} not found in channel manager",
|
||||
trimmedChannelName);
|
||||
if (!chan) {
|
||||
debug::Log("[IrcMessageHandler:handleClearChatMessage] Twitch channel {} not found",
|
||||
chanName);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the chat has been cleared by a moderator
|
||||
if (message->parameters().length() == 1) {
|
||||
c->addMessage(Message::createSystemMessage("Chat has been cleared by a moderator."));
|
||||
chan->addMessage(Message::createSystemMessage("Chat has been cleared by a moderator."));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -92,7 +102,7 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
|||
}
|
||||
|
||||
// add the notice that the user has been timed out
|
||||
LimitedQueueSnapshot<MessagePtr> snapshot = c->getMessageSnapshot();
|
||||
LimitedQueueSnapshot<MessagePtr> snapshot = chan->getMessageSnapshot();
|
||||
bool addMessage = true;
|
||||
int snapshotLength = snapshot.getLength();
|
||||
|
||||
|
@ -100,14 +110,14 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
|||
if (snapshot[i]->flags & Message::Timeout && snapshot[i]->loginName == username) {
|
||||
MessagePtr replacement(
|
||||
Message::createTimeoutMessage(username, durationInSeconds, reason, true));
|
||||
c->replaceMessage(snapshot[i], replacement);
|
||||
chan->replaceMessage(snapshot[i], replacement);
|
||||
addMessage = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addMessage) {
|
||||
c->addMessage(Message::createTimeoutMessage(username, durationInSeconds, reason, false));
|
||||
chan->addMessage(Message::createTimeoutMessage(username, durationInSeconds, reason, false));
|
||||
}
|
||||
|
||||
// disable the messages from the user
|
||||
|
@ -118,7 +128,7 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
|||
}
|
||||
|
||||
// refresh all
|
||||
WindowManager::getInstance().repaintVisibleChatWidgets(c.get());
|
||||
WindowManager::getInstance().repaintVisibleChatWidgets(chan.get());
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message)
|
||||
|
@ -129,7 +139,7 @@ void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message)
|
|||
auto rawChannelName = message->parameters().at(0);
|
||||
auto trimmedChannelName = rawChannelName.mid(1);
|
||||
|
||||
auto c = this->channelManager.getTwitchChannel(trimmedChannelName);
|
||||
auto c = TwitchServer::getInstance().getChannel(trimmedChannelName);
|
||||
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(c.get());
|
||||
if (tc != nullptr) {
|
||||
tc->setMod(_mod == "1");
|
||||
|
@ -149,7 +159,8 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message)
|
|||
|
||||
void IrcMessageHandler::handleModeMessage(Communi::IrcMessage *message)
|
||||
{
|
||||
auto channel = channelManager.getTwitchChannel(message->parameter(0).remove(0, 1));
|
||||
auto channel = TwitchServer::getInstance().getChannel(message->parameter(0).remove(0, 1));
|
||||
|
||||
if (message->parameter(1) == "+o") {
|
||||
channel->modList.append(message->parameter(2));
|
||||
} else if (message->parameter(1) == "-o") {
|
||||
|
@ -165,24 +176,25 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
|||
MessagePtr msg = Message::createSystemMessage(message->content());
|
||||
|
||||
if (broadcast) {
|
||||
this->channelManager.doOnAll([msg](const auto &c) {
|
||||
c->addMessage(msg); //
|
||||
});
|
||||
// fourtf: send to all twitch channels
|
||||
// this->channelManager.doOnAll([msg](const auto &c) {
|
||||
// c->addMessage(msg); //
|
||||
// });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto trimmedChannelName = rawChannelName.mid(1);
|
||||
|
||||
auto c = this->channelManager.getTwitchChannel(trimmedChannelName);
|
||||
auto channel = TwitchServer::getInstance().getChannel(trimmedChannelName);
|
||||
|
||||
if (!c) {
|
||||
if (!channel) {
|
||||
debug::Log("[IrcManager:handleNoticeMessage] Channel {} not found in channel manager",
|
||||
trimmedChannelName);
|
||||
return;
|
||||
}
|
||||
|
||||
c->addMessage(msg);
|
||||
channel->addMessage(msg);
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleWriteConnectionNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||
|
@ -202,6 +214,6 @@ void IrcMessageHandler::handleWriteConnectionNoticeMessage(Communi::IrcNoticeMes
|
|||
|
||||
this->handleNoticeMessage(message);
|
||||
}
|
||||
} // namespace helper
|
||||
} // namespace singletons
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -6,14 +6,15 @@ namespace chatterino {
|
|||
namespace singletons {
|
||||
class ChannelManager;
|
||||
class ResourceManager;
|
||||
} // namespace singletons
|
||||
|
||||
namespace helper {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
class IrcMessageHandler
|
||||
{
|
||||
IrcMessageHandler(ChannelManager &channelManager, ResourceManager &resourceManager);
|
||||
IrcMessageHandler(singletons::ResourceManager &resourceManager);
|
||||
|
||||
ChannelManager &channelManager;
|
||||
ResourceManager &resourceManager;
|
||||
singletons::ResourceManager &resourceManager;
|
||||
|
||||
public:
|
||||
static IrcMessageHandler &getInstance();
|
||||
|
@ -27,6 +28,6 @@ public:
|
|||
void handleNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||
void handleWriteConnectionNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
70
src/providers/twitch/twitchaccount.cpp
Normal file
70
src/providers/twitch/twitchaccount.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "providers/twitch/twitchaccount.hpp"
|
||||
#include "const.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
TwitchAccount::TwitchAccount(const QString &_username, const QString &_oauthToken,
|
||||
const QString &_oauthClient)
|
||||
: userName(_username)
|
||||
, oauthClient(_oauthClient)
|
||||
, oauthToken(_oauthToken)
|
||||
, _isAnon(_username == ANONYMOUS_USERNAME)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &TwitchAccount::getUserName() const
|
||||
{
|
||||
return this->userName;
|
||||
}
|
||||
|
||||
const QString &TwitchAccount::getOAuthClient() const
|
||||
{
|
||||
return this->oauthClient;
|
||||
}
|
||||
|
||||
const QString &TwitchAccount::getOAuthToken() const
|
||||
{
|
||||
return this->oauthToken;
|
||||
}
|
||||
|
||||
const QString &TwitchAccount::getUserId() const
|
||||
{
|
||||
return this->userId;
|
||||
}
|
||||
|
||||
void TwitchAccount::setUserId(const QString &id)
|
||||
{
|
||||
this->userId = id;
|
||||
}
|
||||
|
||||
bool TwitchAccount::setOAuthClient(const QString &newClientID)
|
||||
{
|
||||
if (this->oauthClient.compare(newClientID) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->oauthClient = newClientID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwitchAccount::setOAuthToken(const QString &newOAuthToken)
|
||||
{
|
||||
if (this->oauthToken.compare(newOAuthToken) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->oauthToken = newOAuthToken;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwitchAccount::isAnon() const
|
||||
{
|
||||
return this->_isAnon;
|
||||
}
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -1,19 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "ircaccount.hpp"
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
class TwitchUser : public IrcUser2
|
||||
class TwitchAccount
|
||||
{
|
||||
public:
|
||||
TwitchUser(const QString &username, const QString &oauthToken, const QString &oauthClient);
|
||||
TwitchAccount(const QString &username, const QString &oauthToken, const QString &oauthClient);
|
||||
|
||||
const QString &getUserName() const;
|
||||
const QString &getOAuthToken() const;
|
||||
const QString &getOAuthClient() const;
|
||||
|
||||
const QString &getUserId() const;
|
||||
void setUserId(const QString &id);
|
||||
|
||||
|
@ -28,11 +28,12 @@ public:
|
|||
bool isAnon() const;
|
||||
|
||||
private:
|
||||
QString _oauthClient;
|
||||
QString _oauthToken;
|
||||
QString _userId;
|
||||
QString oauthClient;
|
||||
QString oauthToken;
|
||||
QString userId;
|
||||
QString userName;
|
||||
const bool _isAnon;
|
||||
};
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -1,15 +1,16 @@
|
|||
#include "twitchaccountmanager.hpp"
|
||||
#include "providers/twitch/twitchaccountmanager.hpp"
|
||||
|
||||
#include "common.hpp"
|
||||
#include "const.hpp"
|
||||
#include "debug/log.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
TwitchAccountManager::TwitchAccountManager()
|
||||
{
|
||||
this->anonymousUser.reset(new twitch::TwitchUser(twitch::ANONYMOUS_USERNAME, "", ""));
|
||||
this->anonymousUser.reset(new TwitchAccount(ANONYMOUS_USERNAME, "", ""));
|
||||
|
||||
this->currentUsername.connect([this](const auto &newValue, auto) {
|
||||
QString newUsername(QString::fromStdString(newValue));
|
||||
|
@ -28,7 +29,7 @@ TwitchAccountManager::TwitchAccountManager()
|
|||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<twitch::TwitchUser> TwitchAccountManager::getCurrent()
|
||||
std::shared_ptr<TwitchAccount> TwitchAccountManager::getCurrent()
|
||||
{
|
||||
if (!this->currentUser) {
|
||||
return this->anonymousUser;
|
||||
|
@ -50,7 +51,7 @@ std::vector<QString> TwitchAccountManager::getUsernames() const
|
|||
return userNames;
|
||||
}
|
||||
|
||||
std::shared_ptr<twitch::TwitchUser> TwitchAccountManager::findUserByUsername(
|
||||
std::shared_ptr<TwitchAccount> TwitchAccountManager::findUserByUsername(
|
||||
const QString &username) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->mutex);
|
||||
|
@ -107,7 +108,7 @@ void TwitchAccountManager::reloadUsers()
|
|||
} break;
|
||||
case AddUserResponse::UserValuesUpdated: {
|
||||
debug::Log("User {} already exists, and values updated!", userData.username);
|
||||
if (userData.username == this->getCurrent()->getNickName()) {
|
||||
if (userData.username == this->getCurrent()->getUserName()) {
|
||||
debug::Log("It was the current user, so we need to reconnect stuff!");
|
||||
this->userChanged.invoke();
|
||||
}
|
||||
|
@ -132,7 +133,7 @@ bool TwitchAccountManager::removeUser(const QString &username)
|
|||
|
||||
this->mutex.lock();
|
||||
this->users.erase(std::remove_if(this->users.begin(), this->users.end(), [username](auto user) {
|
||||
if (user->getNickName() == username) {
|
||||
if (user->getUserName() == username) {
|
||||
std::string userID(user->getUserId().toStdString());
|
||||
assert(!userID.empty());
|
||||
pajlada::Settings::SettingManager::removeSetting("/accounts/uid" + userID);
|
||||
|
@ -174,8 +175,8 @@ TwitchAccountManager::AddUserResponse TwitchAccountManager::addUser(
|
|||
}
|
||||
}
|
||||
|
||||
auto newUser = std::make_shared<twitch::TwitchUser>(userData.username, userData.oauthToken,
|
||||
userData.clientID);
|
||||
auto newUser =
|
||||
std::make_shared<TwitchAccount>(userData.username, userData.oauthToken, userData.clientID);
|
||||
|
||||
// Set users User ID without the uid prefix
|
||||
newUser->setUserId(userData.userID);
|
||||
|
@ -188,4 +189,5 @@ TwitchAccountManager::AddUserResponse TwitchAccountManager::addUser(
|
|||
}
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "twitch/twitchuser.hpp"
|
||||
#include "providers/twitch/twitchaccount.hpp"
|
||||
|
||||
#include <pajlada/settings/setting.hpp>
|
||||
|
||||
|
@ -16,9 +16,8 @@ namespace chatterino {
|
|||
namespace singletons {
|
||||
class AccountManager;
|
||||
}
|
||||
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
class TwitchAccountManager
|
||||
{
|
||||
TwitchAccountManager();
|
||||
|
@ -32,11 +31,11 @@ public:
|
|||
};
|
||||
|
||||
// Returns the current twitchUsers, or the anonymous user if we're not currently logged in
|
||||
std::shared_ptr<twitch::TwitchUser> getCurrent();
|
||||
std::shared_ptr<TwitchAccount> getCurrent();
|
||||
|
||||
std::vector<QString> getUsernames() const;
|
||||
|
||||
std::shared_ptr<twitch::TwitchUser> findUserByUsername(const QString &username) const;
|
||||
std::shared_ptr<TwitchAccount> findUserByUsername(const QString &username) const;
|
||||
bool userExists(const QString &username) const;
|
||||
|
||||
void reloadUsers();
|
||||
|
@ -55,14 +54,14 @@ private:
|
|||
};
|
||||
AddUserResponse addUser(const UserData &data);
|
||||
|
||||
std::shared_ptr<twitch::TwitchUser> currentUser;
|
||||
std::shared_ptr<TwitchAccount> currentUser;
|
||||
|
||||
std::shared_ptr<twitch::TwitchUser> anonymousUser;
|
||||
std::vector<std::shared_ptr<twitch::TwitchUser>> users;
|
||||
std::shared_ptr<TwitchAccount> anonymousUser;
|
||||
std::vector<std::shared_ptr<TwitchAccount>> users;
|
||||
mutable std::mutex mutex;
|
||||
|
||||
friend class chatterino::singletons::AccountManager;
|
||||
};
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -1,20 +1,22 @@
|
|||
#include "twitchchannel.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "debug/log.hpp"
|
||||
#include "messages/message.hpp"
|
||||
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||
#include "singletons/channelmanager.hpp"
|
||||
#include "singletons/emotemanager.hpp"
|
||||
#include "singletons/ircmanager.hpp"
|
||||
#include "singletons/settingsmanager.hpp"
|
||||
#include "twitch/twitchmessagebuilder.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
|
||||
#include <IrcConnection>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
TwitchChannel::TwitchChannel(const QString &channelName)
|
||||
TwitchChannel::TwitchChannel(const QString &channelName, Communi::IrcConnection *_readConnection)
|
||||
: Channel(channelName)
|
||||
, bttvChannelEmotes(new util::EmoteMap)
|
||||
, ffzChannelEmotes(new util::EmoteMap)
|
||||
|
@ -23,6 +25,7 @@ TwitchChannel::TwitchChannel(const QString &channelName)
|
|||
, popoutPlayerURL("https://player.twitch.tv/?channel=" + name)
|
||||
, isLive(false)
|
||||
, mod(false)
|
||||
, readConnecetion(_readConnection)
|
||||
{
|
||||
debug::Log("[TwitchChannel:{}] Opened", this->name);
|
||||
|
||||
|
@ -42,9 +45,6 @@ TwitchChannel::TwitchChannel(const QString &channelName)
|
|||
this->fetchRecentMessages(); //
|
||||
});
|
||||
|
||||
this->connectedConnection = singletons::IrcManager::getInstance().connected.connect(
|
||||
[this] { this->userStateChanged(); });
|
||||
|
||||
this->messageSuffix.append(' ');
|
||||
this->messageSuffix.append(QChar(0x206D));
|
||||
}
|
||||
|
@ -95,8 +95,9 @@ void TwitchChannel::sendMessage(const QString &message)
|
|||
|
||||
parsedMessage = parsedMessage.trimmed();
|
||||
|
||||
if (parsedMessage.isEmpty())
|
||||
if (parsedMessage.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (singletons::SettingManager::getInstance().allowDuplicateMessages) {
|
||||
if (parsedMessage == this->lastSentMessage) {
|
||||
|
@ -106,7 +107,7 @@ void TwitchChannel::sendMessage(const QString &message)
|
|||
}
|
||||
}
|
||||
|
||||
singletons::IrcManager::getInstance().sendMessage(this->name, parsedMessage);
|
||||
this->sendMessageSignal.invoke(this->name, parsedMessage);
|
||||
}
|
||||
|
||||
bool TwitchChannel::isMod() const
|
||||
|
@ -227,7 +228,7 @@ void TwitchChannel::fetchRecentMessages()
|
|||
}
|
||||
|
||||
TwitchChannel *channel = dynamic_cast<TwitchChannel *>(shared.get());
|
||||
static auto readConnection = singletons::IrcManager::getInstance().getReadConnection();
|
||||
static auto readConnection = channel->readConnecetion;
|
||||
|
||||
auto msgArray = obj.value("messages").toArray();
|
||||
if (msgArray.size() > 0) {
|
||||
|
@ -249,4 +250,5 @@ void TwitchChannel::fetchRecentMessages()
|
|||
});
|
||||
}
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -1,19 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <IrcConnection>
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "singletons/emotemanager.hpp"
|
||||
#include "singletons/ircmanager.hpp"
|
||||
#include "util/concurrentmap.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
class TwitchChannel : public Channel
|
||||
class TwitchServer;
|
||||
class TwitchChannel final : public Channel
|
||||
{
|
||||
QTimer *liveStatusTimer;
|
||||
|
||||
public:
|
||||
explicit TwitchChannel(const QString &channelName);
|
||||
~TwitchChannel();
|
||||
|
||||
void reloadChannelEmotes();
|
||||
|
@ -49,6 +52,8 @@ public:
|
|||
QString streamUptime;
|
||||
|
||||
private:
|
||||
explicit TwitchChannel(const QString &channelName, Communi::IrcConnection *readConnection);
|
||||
|
||||
void setLive(bool newLiveStatus);
|
||||
void refreshLiveStatus();
|
||||
|
||||
|
@ -59,7 +64,11 @@ private:
|
|||
bool mod;
|
||||
QByteArray messageSuffix;
|
||||
QString lastSentMessage;
|
||||
};
|
||||
|
||||
Communi::IrcConnection *readConnecetion;
|
||||
|
||||
friend class TwitchServer;
|
||||
};
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -1,12 +1,12 @@
|
|||
#include "twitchmessagebuilder.hpp"
|
||||
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||
#include "debug/log.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
#include "singletons/emotemanager.hpp"
|
||||
#include "singletons/ircmanager.hpp"
|
||||
#include "singletons/resourcemanager.hpp"
|
||||
#include "singletons/settingsmanager.hpp"
|
||||
#include "singletons/thememanager.hpp"
|
||||
#include "singletons/windowmanager.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
@ -15,6 +15,7 @@
|
|||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel,
|
||||
|
@ -707,4 +708,5 @@ bool TwitchMessageBuilder::tryParseCheermote(const QString &string)
|
|||
return false;
|
||||
}
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -12,6 +12,7 @@
|
|||
namespace chatterino {
|
||||
class Channel;
|
||||
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
class TwitchChannel;
|
||||
|
||||
|
@ -64,4 +65,5 @@ private:
|
|||
};
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
148
src/providers/twitch/twitchserver.cpp
Normal file
148
src/providers/twitch/twitchserver.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
#include "twitchserver.hpp"
|
||||
|
||||
#include "providers/twitch/ircmessagehandler.hpp"
|
||||
#include "providers/twitch/twitchaccount.hpp"
|
||||
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||
#include "singletons/accountmanager.hpp"
|
||||
#include "util/posttothread.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace Communi;
|
||||
using namespace chatterino::singletons;
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
TwitchServer::TwitchServer()
|
||||
: whispersChannel(new Channel("/mentions"))
|
||||
, mentionsChannel(new Channel("/mentions"))
|
||||
{
|
||||
AccountManager::getInstance().Twitch.userChanged.connect([this]() { //
|
||||
util::postToThread([this] { this->connect(); });
|
||||
});
|
||||
}
|
||||
|
||||
TwitchServer &TwitchServer::getInstance()
|
||||
{
|
||||
static TwitchServer s;
|
||||
return s;
|
||||
}
|
||||
|
||||
void TwitchServer::initializeConnection(IrcConnection *connection, bool isRead, bool isWrite)
|
||||
{
|
||||
std::shared_ptr<TwitchAccount> account = AccountManager::getInstance().Twitch.getCurrent();
|
||||
|
||||
QString username = account->getUserName();
|
||||
// QString oauthClient = account->getOAuthClient();
|
||||
QString oauthToken = account->getOAuthToken();
|
||||
|
||||
if (!oauthToken.startsWith("oauth:")) {
|
||||
oauthToken.prepend("oauth:");
|
||||
}
|
||||
|
||||
connection->setUserName(username);
|
||||
connection->setNickName(username);
|
||||
connection->setRealName(username);
|
||||
|
||||
if (!account->isAnon()) {
|
||||
connection->setPassword(oauthToken);
|
||||
|
||||
// fourtf: ignored users
|
||||
// this->refreshIgnoredUsers(username, oauthClient, oauthToken);
|
||||
}
|
||||
|
||||
connection->sendCommand(IrcCommand::createCapability("REQ", "twitch.tv/membership"));
|
||||
connection->sendCommand(IrcCommand::createCapability("REQ", "twitch.tv/commands"));
|
||||
connection->sendCommand(IrcCommand::createCapability("REQ", "twitch.tv/tags"));
|
||||
|
||||
connection->setHost("irc.chat.twitch.tv");
|
||||
connection->setPort(6667);
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> TwitchServer::createChannel(const QString &channelName)
|
||||
{
|
||||
TwitchChannel *channel = new TwitchChannel(channelName, this->getReadConnection());
|
||||
|
||||
channel->sendMessageSignal.connect(
|
||||
[this](auto chan, auto msg) { this->sendMessage(chan, msg); });
|
||||
|
||||
return std::shared_ptr<Channel>(channel);
|
||||
}
|
||||
|
||||
void TwitchServer::privateMessageReceived(IrcPrivateMessage *message)
|
||||
{
|
||||
this->onPrivateMessage.invoke(message);
|
||||
auto chan = TwitchServer::getInstance().getChannel(message->target().mid(1));
|
||||
|
||||
if (!chan) {
|
||||
return;
|
||||
}
|
||||
|
||||
messages::MessageParseArgs args;
|
||||
|
||||
TwitchMessageBuilder builder(chan.get(), message, args);
|
||||
|
||||
if (!builder.isIgnored()) {
|
||||
messages::MessagePtr _message = builder.build();
|
||||
if (_message->flags & messages::Message::Highlighted) {
|
||||
TwitchServer::getInstance().mentionsChannel->addMessage(_message);
|
||||
}
|
||||
|
||||
chan->addMessage(_message);
|
||||
}
|
||||
}
|
||||
|
||||
void TwitchServer::messageReceived(IrcMessage *message)
|
||||
{
|
||||
// this->readConnection
|
||||
if (message->type() == IrcMessage::Type::Private) {
|
||||
// We already have a handler for private messages
|
||||
return;
|
||||
}
|
||||
|
||||
const QString &command = message->command();
|
||||
|
||||
if (command == "ROOMSTATE") {
|
||||
IrcMessageHandler::getInstance().handleRoomStateMessage(message);
|
||||
} else if (command == "CLEARCHAT") {
|
||||
IrcMessageHandler::getInstance().handleClearChatMessage(message);
|
||||
} else if (command == "USERSTATE") {
|
||||
IrcMessageHandler::getInstance().handleUserStateMessage(message);
|
||||
} else if (command == "WHISPER") {
|
||||
IrcMessageHandler::getInstance().handleWhisperMessage(message);
|
||||
} else if (command == "USERNOTICE") {
|
||||
IrcMessageHandler::getInstance().handleUserNoticeMessage(message);
|
||||
} else if (command == "MODE") {
|
||||
IrcMessageHandler::getInstance().handleModeMessage(message);
|
||||
} else if (command == "NOTICE") {
|
||||
IrcMessageHandler::getInstance().handleNoticeMessage(
|
||||
static_cast<IrcNoticeMessage *>(message));
|
||||
}
|
||||
}
|
||||
|
||||
void TwitchServer::writeConnectionMessageReceived(IrcMessage *message)
|
||||
{
|
||||
switch (message->type()) {
|
||||
case IrcMessage::Type::Notice: {
|
||||
IrcMessageHandler::getInstance().handleWriteConnectionNoticeMessage(
|
||||
static_cast<IrcNoticeMessage *>(message));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> TwitchServer::getCustomChannel(const QString &channelName)
|
||||
{
|
||||
if (channelName == "/whispers") {
|
||||
return whispersChannel;
|
||||
}
|
||||
|
||||
if (channelName == "/mentions") {
|
||||
return mentionsChannel;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
35
src/providers/twitch/twitchserver.hpp
Normal file
35
src/providers/twitch/twitchserver.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "providers/irc/abstractircserver.hpp"
|
||||
#include "providers/twitch/twitchaccount.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
class TwitchServer final : public irc::AbstractIrcServer
|
||||
{
|
||||
TwitchServer();
|
||||
|
||||
public:
|
||||
static TwitchServer &getInstance();
|
||||
|
||||
const ChannelPtr whispersChannel;
|
||||
const ChannelPtr mentionsChannel;
|
||||
|
||||
protected:
|
||||
virtual void initializeConnection(Communi::IrcConnection *connection, bool isRead,
|
||||
bool isWrite) override;
|
||||
virtual std::shared_ptr<Channel> createChannel(const QString &channelName) override;
|
||||
|
||||
virtual void privateMessageReceived(Communi::IrcPrivateMessage *message) override;
|
||||
virtual void messageReceived(Communi::IrcMessage *message) override;
|
||||
virtual void writeConnectionMessageReceived(Communi::IrcMessage *message) override;
|
||||
|
||||
virtual std::shared_ptr<Channel> getCustomChannel(const QString &channelname) override;
|
||||
};
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
|
@ -43,5 +43,5 @@ void AccountManager::load()
|
|||
this->Twitch.userChanged.invoke();
|
||||
}
|
||||
|
||||
} // namespace singletons
|
||||
} // namespace chatterino
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "twitch/twitchaccountmanager.hpp"
|
||||
#include "providers/twitch/twitchaccountmanager.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
|
@ -14,7 +14,7 @@ public:
|
|||
|
||||
void load();
|
||||
|
||||
twitch::TwitchAccountManager Twitch;
|
||||
providers::twitch::TwitchAccountManager Twitch;
|
||||
};
|
||||
|
||||
} // namespace singletons
|
||||
|
|
|
@ -1,142 +1,140 @@
|
|||
#include "singletons/channelmanager.hpp"
|
||||
#include "singletons/ircmanager.hpp"
|
||||
//#include "singletons/channelmanager.hpp"
|
||||
//#include "singletons/ircmanager.hpp"
|
||||
|
||||
using namespace chatterino::twitch;
|
||||
// namespace chatterino {
|
||||
// namespace singletons {
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
// ChannelManager &ChannelManager::getInstance()
|
||||
//{
|
||||
// static ChannelManager instance;
|
||||
// return instance;
|
||||
//}
|
||||
|
||||
ChannelManager &ChannelManager::getInstance()
|
||||
{
|
||||
static ChannelManager instance;
|
||||
return instance;
|
||||
}
|
||||
// ChannelManager::ChannelManager()
|
||||
// : whispersChannel(new Channel("/whispers"))
|
||||
// , mentionsChannel(new Channel("/mentions"))
|
||||
// , emptyChannel(new Channel(""))
|
||||
//{
|
||||
//}
|
||||
|
||||
ChannelManager::ChannelManager()
|
||||
: whispersChannel(new Channel("/whispers"))
|
||||
, mentionsChannel(new Channel("/mentions"))
|
||||
, emptyChannel(new Channel(""))
|
||||
{
|
||||
}
|
||||
// const std::vector<ChannelPtr> ChannelManager::getItems()
|
||||
//{
|
||||
// QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
const std::vector<ChannelPtr> ChannelManager::getItems()
|
||||
{
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
// std::vector<ChannelPtr> items;
|
||||
|
||||
std::vector<ChannelPtr> items;
|
||||
// for (auto &item : this->twitchChannels.values()) {
|
||||
// items.push_back(std::get<0>(item));
|
||||
// }
|
||||
|
||||
for (auto &item : this->twitchChannels.values()) {
|
||||
items.push_back(std::get<0>(item));
|
||||
}
|
||||
// return items;
|
||||
//}
|
||||
|
||||
return items;
|
||||
}
|
||||
// ChannelPtr ChannelManager::addTwitchChannel(const QString &rawChannelName)
|
||||
//{
|
||||
// QString channelName = rawChannelName.toLower();
|
||||
|
||||
ChannelPtr ChannelManager::addTwitchChannel(const QString &rawChannelName)
|
||||
{
|
||||
QString channelName = rawChannelName.toLower();
|
||||
// if (channelName.length() > 1 && channelName.at(0) == '/') {
|
||||
// return this->getTwitchChannel(channelName);
|
||||
// }
|
||||
|
||||
if (channelName.length() > 1 && channelName.at(0) == '/') {
|
||||
return this->getTwitchChannel(channelName);
|
||||
}
|
||||
// if (channelName.length() > 0 && channelName.at(0) == '#') {
|
||||
// channelName = channelName.mid(1);
|
||||
// }
|
||||
|
||||
if (channelName.length() > 0 && channelName.at(0) == '#') {
|
||||
channelName = channelName.mid(1);
|
||||
}
|
||||
// QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
// auto it = this->twitchChannels.find(channelName);
|
||||
|
||||
auto it = this->twitchChannels.find(channelName);
|
||||
// if (it == this->twitchChannels.end()) {
|
||||
// auto channel = std::make_shared<TwitchChannel>(channelName);
|
||||
|
||||
if (it == this->twitchChannels.end()) {
|
||||
auto channel = std::make_shared<TwitchChannel>(channelName);
|
||||
// this->twitchChannels.insert(channelName, std::make_tuple(channel, 1));
|
||||
|
||||
this->twitchChannels.insert(channelName, std::make_tuple(channel, 1));
|
||||
// this->ircJoin.invoke(channelName);
|
||||
|
||||
this->ircJoin.invoke(channelName);
|
||||
// return channel;
|
||||
// }
|
||||
|
||||
return channel;
|
||||
}
|
||||
// std::get<1>(it.value())++;
|
||||
|
||||
std::get<1>(it.value())++;
|
||||
// return std::get<0>(it.value());
|
||||
//}
|
||||
|
||||
return std::get<0>(it.value());
|
||||
}
|
||||
// ChannelPtr ChannelManager::getTwitchChannel(const QString &channel)
|
||||
//{
|
||||
// QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
ChannelPtr ChannelManager::getTwitchChannel(const QString &channel)
|
||||
{
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
// QString c = channel.toLower();
|
||||
|
||||
QString c = channel.toLower();
|
||||
// if (channel.length() > 1 && channel.at(0) == '/') {
|
||||
// if (c == "/whispers") {
|
||||
// return whispersChannel;
|
||||
// }
|
||||
|
||||
if (channel.length() > 1 && channel.at(0) == '/') {
|
||||
if (c == "/whispers") {
|
||||
return whispersChannel;
|
||||
}
|
||||
// if (c == "/mentions") {
|
||||
// return mentionsChannel;
|
||||
// }
|
||||
|
||||
if (c == "/mentions") {
|
||||
return mentionsChannel;
|
||||
}
|
||||
// return emptyChannel;
|
||||
// }
|
||||
|
||||
return emptyChannel;
|
||||
}
|
||||
// auto a = this->twitchChannels.find(c);
|
||||
|
||||
auto a = this->twitchChannels.find(c);
|
||||
// if (a == this->twitchChannels.end()) {
|
||||
// return emptyChannel;
|
||||
// }
|
||||
|
||||
if (a == this->twitchChannels.end()) {
|
||||
return emptyChannel;
|
||||
}
|
||||
// return std::get<0>(a.value());
|
||||
//}
|
||||
|
||||
return std::get<0>(a.value());
|
||||
}
|
||||
// void ChannelManager::removeTwitchChannel(const QString &channel)
|
||||
//{
|
||||
// QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
void ChannelManager::removeTwitchChannel(const QString &channel)
|
||||
{
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
// if (channel.length() > 1 && channel.at(0) == '/') {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (channel.length() > 1 && channel.at(0) == '/') {
|
||||
return;
|
||||
}
|
||||
// QString c = channel.toLower();
|
||||
|
||||
QString c = channel.toLower();
|
||||
// auto a = this->twitchChannels.find(c);
|
||||
|
||||
auto a = this->twitchChannels.find(c);
|
||||
// if (a == this->twitchChannels.end()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (a == this->twitchChannels.end()) {
|
||||
return;
|
||||
}
|
||||
// std::get<1>(a.value())--;
|
||||
|
||||
std::get<1>(a.value())--;
|
||||
// if (std::get<1>(a.value()) == 0) {
|
||||
// this->ircPart.invoke(c);
|
||||
// this->twitchChannels.remove(c);
|
||||
// }
|
||||
//}
|
||||
|
||||
if (std::get<1>(a.value()) == 0) {
|
||||
this->ircPart.invoke(c);
|
||||
this->twitchChannels.remove(c);
|
||||
}
|
||||
}
|
||||
// const std::string &ChannelManager::getUserID(const std::string &username)
|
||||
//{
|
||||
// /* TODO: Implement
|
||||
// auto it = this->usernameToID.find(username);
|
||||
|
||||
const std::string &ChannelManager::getUserID(const std::string &username)
|
||||
{
|
||||
/* TODO: Implement
|
||||
auto it = this->usernameToID.find(username);
|
||||
// if (it != std::end(this->usernameToID)) {
|
||||
// return *it;
|
||||
// }
|
||||
// */
|
||||
|
||||
if (it != std::end(this->usernameToID)) {
|
||||
return *it;
|
||||
}
|
||||
*/
|
||||
// static std::string temporary = "xd";
|
||||
// return temporary;
|
||||
//}
|
||||
|
||||
static std::string temporary = "xd";
|
||||
return temporary;
|
||||
}
|
||||
// void ChannelManager::doOnAll(std::function<void(ChannelPtr)> func)
|
||||
//{
|
||||
// for (const auto &channel : this->twitchChannels) {
|
||||
// func(std::get<0>(channel));
|
||||
// }
|
||||
|
||||
void ChannelManager::doOnAll(std::function<void(ChannelPtr)> func)
|
||||
{
|
||||
for (const auto &channel : this->twitchChannels) {
|
||||
func(std::get<0>(channel));
|
||||
}
|
||||
// func(this->whispersChannel);
|
||||
// func(this->mentionsChannel);
|
||||
//}
|
||||
|
||||
func(this->whispersChannel);
|
||||
func(this->mentionsChannel);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
}
|
||||
//} // namespace singletons
|
||||
//} // namespace chatterino
|
||||
|
|
|
@ -1,49 +1,44 @@
|
|||
#pragma once
|
||||
//#pragma once
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "channeldata.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
//#include "channel.hpp"
|
||||
//#include "channeldata.hpp"
|
||||
//#include "providers/twitch/twitchchannel.hpp"
|
||||
|
||||
#include <map>
|
||||
//#include <map>
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
class IrcManager;
|
||||
// namespace chatterino {
|
||||
// namespace singletons {
|
||||
// class IrcManager;
|
||||
|
||||
class ChannelManager
|
||||
{
|
||||
explicit ChannelManager();
|
||||
// class ChannelManager
|
||||
//{
|
||||
// explicit ChannelManager();
|
||||
|
||||
public:
|
||||
static ChannelManager &getInstance();
|
||||
// public:
|
||||
// static ChannelManager &getInstance();
|
||||
|
||||
const std::vector<ChannelPtr> getItems();
|
||||
// const std::vector<ChannelPtr> getItems();
|
||||
|
||||
ChannelPtr addTwitchChannel(const QString &channel);
|
||||
ChannelPtr getTwitchChannel(const QString &channel);
|
||||
void removeTwitchChannel(const QString &channel);
|
||||
// const std::string &getUserID(const std::string &username);
|
||||
|
||||
const std::string &getUserID(const std::string &username);
|
||||
// void doOnAll(std::function<void(ChannelPtr)> func);
|
||||
|
||||
void doOnAll(std::function<void(ChannelPtr)> func);
|
||||
// // Special channels
|
||||
// const ChannelPtr whispersChannel;
|
||||
// const ChannelPtr mentionsChannel;
|
||||
// const ChannelPtr emptyChannel;
|
||||
|
||||
// Special channels
|
||||
const ChannelPtr whispersChannel;
|
||||
const ChannelPtr mentionsChannel;
|
||||
const ChannelPtr emptyChannel;
|
||||
// private:
|
||||
// std::map<std::string, std::string> usernameToID;
|
||||
// std::map<std::string, ChannelData> channelDatas;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> usernameToID;
|
||||
std::map<std::string, ChannelData> channelDatas;
|
||||
// QMutex channelsMutex;
|
||||
// QMap<QString, std::tuple<std::shared_ptr<TwitchChannel>, int>> twitchChannels;
|
||||
|
||||
QMutex channelsMutex;
|
||||
QMap<QString, std::tuple<std::shared_ptr<twitch::TwitchChannel>, int>> twitchChannels;
|
||||
// pajlada::Signals::Signal<const QString &> ircJoin;
|
||||
// pajlada::Signals::Signal<const QString &> ircPart;
|
||||
|
||||
pajlada::Signals::Signal<const QString &> ircJoin;
|
||||
pajlada::Signals::Signal<const QString &> ircPart;
|
||||
|
||||
friend class singletons::IrcManager;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
}
|
||||
// friend class singletons::IrcManager;
|
||||
//};
|
||||
//} // namespace singletons
|
||||
//} // namespace chatterino
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include <QRegularExpression>
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
|
||||
using namespace chatterino::providers::twitch;
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
|
@ -88,8 +90,7 @@ QStringList CommandManager::getCommands()
|
|||
return this->commandsStringList;
|
||||
}
|
||||
|
||||
QString CommandManager::execCommand(const QString &text, ChannelPtr channel,
|
||||
bool dryRun)
|
||||
QString CommandManager::execCommand(const QString &text, ChannelPtr channel, bool dryRun)
|
||||
{
|
||||
QStringList words = text.split(' ', QString::SkipEmptyParts);
|
||||
Command command;
|
||||
|
@ -104,7 +105,7 @@ QString CommandManager::execCommand(const QString &text, ChannelPtr channel,
|
|||
QString commandName = words[0];
|
||||
|
||||
// check if default command exists
|
||||
auto *twitchChannel = dynamic_cast<twitch::TwitchChannel *>(channel.get());
|
||||
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
||||
|
||||
if (!dryRun && twitchChannel != nullptr) {
|
||||
if (commandName == "/uptime") {
|
||||
|
@ -115,22 +116,26 @@ QString CommandManager::execCommand(const QString &text, ChannelPtr channel,
|
|||
|
||||
return "";
|
||||
} else if (commandName == "/ignore" && words.size() >= 2) {
|
||||
QString messageText;
|
||||
// fourtf: ignore user
|
||||
// QString messageText;
|
||||
|
||||
if (IrcManager::getInstance().tryAddIgnoredUser(words.at(1), messageText)) {
|
||||
messageText = "Ignored user \"" + words.at(1) + "\".";
|
||||
}
|
||||
// if (IrcManager::getInstance().tryAddIgnoredUser(words.at(1),
|
||||
// messageText)) {
|
||||
// messageText = "Ignored user \"" + words.at(1) + "\".";
|
||||
// }
|
||||
|
||||
channel->addMessage(messages::Message::createSystemMessage(messageText));
|
||||
// channel->addMessage(messages::Message::createSystemMessage(messageText));
|
||||
return "";
|
||||
} else if (commandName == "/unignore") {
|
||||
QString messageText;
|
||||
// fourtf: ignore user
|
||||
// QString messageText;
|
||||
|
||||
if (IrcManager::getInstance().tryRemoveIgnoredUser(words.at(1), messageText)) {
|
||||
messageText = "Ignored user \"" + words.at(1) + "\".";
|
||||
}
|
||||
// if (IrcManager::getInstance().tryRemoveIgnoredUser(words.at(1),
|
||||
// messageText)) {
|
||||
// messageText = "Ignored user \"" + words.at(1) + "\".";
|
||||
// }
|
||||
|
||||
channel->addMessage(messages::Message::createSystemMessage(messageText));
|
||||
// channel->addMessage(messages::Message::createSystemMessage(messageText));
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,18 +13,18 @@ CompletionManager &CompletionManager::getInstance()
|
|||
return instance;
|
||||
}
|
||||
|
||||
CompletionModel *CompletionManager::createModel(const std::string &channelName)
|
||||
CompletionModel *CompletionManager::createModel(const QString &channelName)
|
||||
{
|
||||
auto it = this->models.find(channelName);
|
||||
if (it != this->models.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
CompletionModel *ret = new CompletionModel(qS(channelName));
|
||||
CompletionModel *ret = new CompletionModel(channelName);
|
||||
this->models[channelName] = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace singletons
|
||||
} // namespace chatterino
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@ class CompletionManager
|
|||
public:
|
||||
static CompletionManager &getInstance();
|
||||
|
||||
CompletionModel *createModel(const std::string &channelName);
|
||||
CompletionModel *createModel(const QString &channelName);
|
||||
|
||||
private:
|
||||
std::map<std::string, CompletionModel *> models;
|
||||
std::map<QString, CompletionModel *> models;
|
||||
};
|
||||
|
||||
} // namespace singletons
|
||||
} // namespace chatterino
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#define TWITCH_EMOTE_TEMPLATE "https://static-cdn.jtvnw.net/emoticons/v1/{id}/{scale}"
|
||||
|
||||
using namespace chatterino::providers::twitch;
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
|
@ -206,7 +207,7 @@ void EmoteManager::reloadFFZChannelEmotes(const QString &channelName,
|
|||
});
|
||||
}
|
||||
|
||||
util::ConcurrentMap<QString, twitch::EmoteValue *> &EmoteManager::getTwitchEmotes()
|
||||
util::ConcurrentMap<QString, providers::twitch::EmoteValue *> &EmoteManager::getTwitchEmotes()
|
||||
{
|
||||
return _twitchEmotes;
|
||||
}
|
||||
|
@ -420,9 +421,9 @@ QString EmoteManager::replaceShortCodes(const QString &text)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void EmoteManager::refreshTwitchEmotes(const std::shared_ptr<twitch::TwitchUser> &user)
|
||||
void EmoteManager::refreshTwitchEmotes(const std::shared_ptr<TwitchAccount> &user)
|
||||
{
|
||||
debug::Log("Loading Twitch emotes for user {}", user->getNickName());
|
||||
debug::Log("Loading Twitch emotes for user {}", user->getUserName());
|
||||
|
||||
const auto &roomID = user->getUserId();
|
||||
const auto &clientID = user->getOAuthClient();
|
||||
|
@ -462,9 +463,7 @@ void EmoteManager::refreshTwitchEmotes(const std::shared_ptr<twitch::TwitchUser>
|
|||
}
|
||||
|
||||
emoteData.filled = true;
|
||||
}
|
||||
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void EmoteManager::loadBTTVEmotes()
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
#include "emojis.hpp"
|
||||
#include "messages/image.hpp"
|
||||
#include "providers/twitch/emotevalue.hpp"
|
||||
#include "providers/twitch/twitchaccount.hpp"
|
||||
#include "signalvector.hpp"
|
||||
#include "twitch/emotevalue.hpp"
|
||||
#include "twitch/twitchuser.hpp"
|
||||
#include "util/concurrentmap.hpp"
|
||||
#include "util/emotemap.hpp"
|
||||
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
void reloadFFZChannelEmotes(const QString &channelName,
|
||||
std::weak_ptr<util::EmoteMap> channelEmoteMap);
|
||||
|
||||
util::ConcurrentMap<QString, twitch::EmoteValue *> &getTwitchEmotes();
|
||||
util::ConcurrentMap<QString, providers::twitch::EmoteValue *> &getTwitchEmotes();
|
||||
util::EmoteMap &getFFZEmotes();
|
||||
util::EmoteMap &getChatterinoEmotes();
|
||||
util::EmoteMap &getBTTVChannelEmoteFromCaches();
|
||||
|
@ -92,7 +92,7 @@ public:
|
|||
std::vector<std::string> emojiShortCodes;
|
||||
|
||||
/// Twitch emotes
|
||||
void refreshTwitchEmotes(const std::shared_ptr<twitch::TwitchUser> &user);
|
||||
void refreshTwitchEmotes(const std::shared_ptr<providers::twitch::TwitchAccount> &user);
|
||||
|
||||
struct TwitchAccountEmoteData {
|
||||
struct TwitchEmote {
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
|
||||
private:
|
||||
// emote code
|
||||
util::ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;
|
||||
util::ConcurrentMap<QString, providers::twitch::EmoteValue *> _twitchEmotes;
|
||||
|
||||
// emote id
|
||||
util::ConcurrentMap<long, util::EmoteData> _twitchEmoteFromCache;
|
||||
|
|
|
@ -61,18 +61,19 @@ void CompletionModel::refresh()
|
|||
}
|
||||
|
||||
// Channel-specific: Usernames
|
||||
auto c = singletons::ChannelManager::getInstance().getTwitchChannel(this->channelName);
|
||||
auto usernames = c->getUsernamesForCompletions();
|
||||
for (const auto &name : usernames) {
|
||||
assert(!name.displayName.isEmpty());
|
||||
this->addString(name.displayName);
|
||||
this->addString('@' + name.displayName);
|
||||
// fourtf: only works with twitch chat
|
||||
// auto c = singletons::ChannelManager::getInstance().getTwitchChannel(this->channelName);
|
||||
// auto usernames = c->getUsernamesForCompletions();
|
||||
// for (const auto &name : usernames) {
|
||||
// assert(!name.displayName.isEmpty());
|
||||
// this->addString(name.displayName);
|
||||
// this->addString('@' + name.displayName);
|
||||
|
||||
if (!name.localizedName.isEmpty()) {
|
||||
this->addString(name.localizedName);
|
||||
this->addString('@' + name.localizedName);
|
||||
}
|
||||
}
|
||||
// if (!name.localizedName.isEmpty()) {
|
||||
// this->addString(name.localizedName);
|
||||
// this->addString('@' + name.localizedName);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void CompletionModel::addString(const std::string &str)
|
||||
|
@ -86,5 +87,5 @@ void CompletionModel::addString(const QString &str)
|
|||
// Always add a space at the end of completions
|
||||
this->emotes.push_back(str + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace singletons
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
#include "channel.hpp"
|
||||
#include "debug/log.hpp"
|
||||
#include "messages/messageparseargs.hpp"
|
||||
#include "providers/twitch/twitchaccount.hpp"
|
||||
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||
#include "singletons/accountmanager.hpp"
|
||||
#include "singletons/channelmanager.hpp"
|
||||
#include "singletons/emotemanager.hpp"
|
||||
#include "singletons/helper/ircmessagehandler.hpp"
|
||||
#include "singletons/resourcemanager.hpp"
|
||||
#include "singletons/settingsmanager.hpp"
|
||||
#include "singletons/windowmanager.hpp"
|
||||
#include "twitch/twitchmessagebuilder.hpp"
|
||||
#include "twitch/twitchuser.hpp"
|
||||
#include "util/posttothread.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
|
||||
|
@ -25,412 +24,122 @@
|
|||
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
|
||||
IrcManager::IrcManager(ChannelManager &_channelManager, ResourceManager &_resources,
|
||||
AccountManager &_accountManager)
|
||||
: channelManager(_channelManager)
|
||||
, resources(_resources)
|
||||
, accountManager(_accountManager)
|
||||
{
|
||||
this->account = accountManager.Twitch.getCurrent();
|
||||
accountManager.Twitch.userChanged.connect([this]() {
|
||||
this->setUser(accountManager.Twitch.getCurrent());
|
||||
|
||||
debug::Log("[IrcManager] Reconnecting to Twitch IRC as new user {}",
|
||||
this->account->getUserName());
|
||||
|
||||
postToThread([this] { this->connect(); });
|
||||
});
|
||||
|
||||
// Initialize the connections
|
||||
this->writeConnection.reset(new Communi::IrcConnection);
|
||||
this->writeConnection->moveToThread(QCoreApplication::instance()->thread());
|
||||
|
||||
QObject::connect(this->writeConnection.get(), &Communi::IrcConnection::messageReceived, this,
|
||||
&IrcManager::writeConnectionMessageReceived);
|
||||
|
||||
this->readConnection.reset(new Communi::IrcConnection);
|
||||
this->readConnection->moveToThread(QCoreApplication::instance()->thread());
|
||||
|
||||
// Listen to read connection message signals
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::messageReceived, this,
|
||||
&IrcManager::messageReceived);
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::privateMessageReceived,
|
||||
this, &IrcManager::privateMessageReceived);
|
||||
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::connected, this,
|
||||
&IrcManager::onConnected);
|
||||
QObject::connect(this->readConnection.get(), &Communi::IrcConnection::disconnected, this,
|
||||
&IrcManager::onDisconnected);
|
||||
|
||||
// join and part chats on event
|
||||
ChannelManager::getInstance().ircJoin.connect(
|
||||
[this](const QString &name) { this->joinChannel(name); });
|
||||
ChannelManager::getInstance().ircPart.connect(
|
||||
[this](const QString &name) { this->partChannel(name); });
|
||||
}
|
||||
|
||||
IrcManager &IrcManager::getInstance()
|
||||
{
|
||||
static IrcManager instance(ChannelManager::getInstance(),
|
||||
singletons::ResourceManager::getInstance(),
|
||||
AccountManager::getInstance());
|
||||
return instance;
|
||||
}
|
||||
|
||||
void IrcManager::setUser(std::shared_ptr<twitch::TwitchUser> newAccount)
|
||||
{
|
||||
this->account = newAccount;
|
||||
}
|
||||
|
||||
void IrcManager::connect()
|
||||
{
|
||||
this->disconnect();
|
||||
|
||||
this->initializeConnection(this->writeConnection, false);
|
||||
this->initializeConnection(this->readConnection, true);
|
||||
|
||||
// XXX(pajlada): Disabled the async_exec for now, because if we happen to run the
|
||||
// `beginConnecting` function in a different thread than last time, we won't be able to connect
|
||||
// because we can't clean up the previous connection properly
|
||||
// async_exec([this] { beginConnecting(); });
|
||||
this->beginConnecting();
|
||||
}
|
||||
|
||||
void IrcManager::initializeConnection(const std::unique_ptr<Communi::IrcConnection> &connection,
|
||||
bool isReadConnection)
|
||||
{
|
||||
assert(this->account);
|
||||
|
||||
QString username = this->account->getUserName();
|
||||
QString oauthClient = this->account->getOAuthClient();
|
||||
QString oauthToken = this->account->getOAuthToken();
|
||||
if (!oauthToken.startsWith("oauth:")) {
|
||||
oauthToken.prepend("oauth:");
|
||||
}
|
||||
|
||||
connection->setUserName(username);
|
||||
connection->setNickName(username);
|
||||
connection->setRealName(username);
|
||||
|
||||
if (!this->account->isAnon()) {
|
||||
connection->setPassword(oauthToken);
|
||||
|
||||
this->refreshIgnoredUsers(username, oauthClient, oauthToken);
|
||||
}
|
||||
|
||||
if (isReadConnection) {
|
||||
connection->sendCommand(
|
||||
Communi::IrcCommand::createCapability("REQ", "twitch.tv/membership"));
|
||||
connection->sendCommand(Communi::IrcCommand::createCapability("REQ", "twitch.tv/commands"));
|
||||
connection->sendCommand(Communi::IrcCommand::createCapability("REQ", "twitch.tv/tags"));
|
||||
} else {
|
||||
connection->sendCommand(Communi::IrcCommand::createCapability("REQ", "twitch.tv/tags"));
|
||||
|
||||
connection->sendCommand(
|
||||
Communi::IrcCommand::createCapability("REQ", "twitch.tv/membership"));
|
||||
connection->sendCommand(Communi::IrcCommand::createCapability("REQ", "twitch.tv/commands"));
|
||||
}
|
||||
|
||||
connection->setHost("irc.chat.twitch.tv");
|
||||
connection->setPort(6667);
|
||||
}
|
||||
|
||||
void IrcManager::refreshIgnoredUsers(const QString &username, const QString &oauthClient,
|
||||
const QString &oauthToken)
|
||||
{
|
||||
QString nextLink = "https://api.twitch.tv/kraken/users/" + username + "/blocks?limit=" + 100 +
|
||||
"&client_id=" + oauthClient;
|
||||
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager();
|
||||
QNetworkRequest req(QUrl(nextLink + "&oauth_token=" + oauthToken));
|
||||
QNetworkReply *reply = manager->get(req);
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||
this->twitchBlockedUsersMutex.lock();
|
||||
this->twitchBlockedUsers.clear();
|
||||
this->twitchBlockedUsersMutex.unlock();
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
QJsonObject root = jsonDoc.object();
|
||||
|
||||
// nextLink =
|
||||
// root.value("this->links").toObject().value("next").toString();
|
||||
|
||||
auto blocks = root.value("blocks").toArray();
|
||||
|
||||
this->twitchBlockedUsersMutex.lock();
|
||||
for (QJsonValue block : blocks) {
|
||||
QJsonObject user = block.toObject().value("user").toObject();
|
||||
// displaythis->name
|
||||
this->twitchBlockedUsers.insert(user.value("name").toString().toLower(), true);
|
||||
}
|
||||
this->twitchBlockedUsersMutex.unlock();
|
||||
|
||||
manager->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void IrcManager::beginConnecting()
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(this->connectionMutex);
|
||||
|
||||
for (auto &channel : this->channelManager.getItems()) {
|
||||
this->writeConnection->sendRaw("JOIN #" + channel->name);
|
||||
this->readConnection->sendRaw("JOIN #" + channel->name);
|
||||
}
|
||||
|
||||
this->writeConnection->open();
|
||||
this->readConnection->open();
|
||||
|
||||
this->connected();
|
||||
}
|
||||
|
||||
void IrcManager::disconnect()
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(this->connectionMutex);
|
||||
|
||||
this->readConnection->close();
|
||||
this->writeConnection->close();
|
||||
}
|
||||
|
||||
void IrcManager::sendMessage(const QString &channelName, QString message)
|
||||
{
|
||||
QString trimmedMessage = message.trimmed();
|
||||
if (trimmedMessage.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->connectionMutex.lock();
|
||||
|
||||
if (this->writeConnection) {
|
||||
this->writeConnection->sendRaw("PRIVMSG #" + channelName + " :" + trimmedMessage);
|
||||
}
|
||||
|
||||
this->connectionMutex.unlock();
|
||||
}
|
||||
|
||||
void IrcManager::joinChannel(const QString &channelName)
|
||||
{
|
||||
this->connectionMutex.lock();
|
||||
|
||||
if (this->readConnection && this->writeConnection) {
|
||||
this->readConnection->sendRaw("JOIN #" + channelName);
|
||||
this->writeConnection->sendRaw("JOIN #" + channelName);
|
||||
}
|
||||
|
||||
this->connectionMutex.unlock();
|
||||
}
|
||||
|
||||
void IrcManager::partChannel(const QString &channelName)
|
||||
{
|
||||
this->connectionMutex.lock();
|
||||
|
||||
if (this->readConnection && this->writeConnection) {
|
||||
this->readConnection->sendRaw("PART #" + channelName);
|
||||
this->writeConnection->sendRaw("PART #" + channelName);
|
||||
}
|
||||
|
||||
this->connectionMutex.unlock();
|
||||
}
|
||||
|
||||
void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message)
|
||||
{
|
||||
this->onPrivateMessage.invoke(message);
|
||||
auto c = this->channelManager.getTwitchChannel(message->target().mid(1));
|
||||
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
// auto xd = message->content();
|
||||
// auto xd2 = message->toData();
|
||||
|
||||
// debug::Log("HEHE: {}", xd2.toStdString());
|
||||
|
||||
messages::MessageParseArgs args;
|
||||
|
||||
twitch::TwitchMessageBuilder builder(c.get(), message, args);
|
||||
|
||||
if (!builder.isIgnored()) {
|
||||
messages::MessagePtr _message = builder.build();
|
||||
if (_message->flags & messages::Message::Highlighted) {
|
||||
singletons::ChannelManager::getInstance().mentionsChannel->addMessage(_message);
|
||||
}
|
||||
|
||||
c->addMessage(_message);
|
||||
}
|
||||
}
|
||||
|
||||
void IrcManager::messageReceived(Communi::IrcMessage *message)
|
||||
{
|
||||
if (message->type() == Communi::IrcMessage::Type::Private) {
|
||||
// We already have a handler for private messages
|
||||
return;
|
||||
}
|
||||
|
||||
const QString &command = message->command();
|
||||
|
||||
if (command == "ROOMSTATE") {
|
||||
helper::IrcMessageHandler::getInstance().handleRoomStateMessage(message);
|
||||
} else if (command == "CLEARCHAT") {
|
||||
helper::IrcMessageHandler::getInstance().handleClearChatMessage(message);
|
||||
} else if (command == "USERSTATE") {
|
||||
helper::IrcMessageHandler::getInstance().handleUserStateMessage(message);
|
||||
} else if (command == "WHISPER") {
|
||||
helper::IrcMessageHandler::getInstance().handleWhisperMessage(message);
|
||||
} else if (command == "USERNOTICE") {
|
||||
helper::IrcMessageHandler::getInstance().handleUserNoticeMessage(message);
|
||||
} else if (command == "MODE") {
|
||||
helper::IrcMessageHandler::getInstance().handleModeMessage(message);
|
||||
} else if (command == "NOTICE") {
|
||||
helper::IrcMessageHandler::getInstance().handleNoticeMessage(
|
||||
static_cast<Communi::IrcNoticeMessage *>(message));
|
||||
}
|
||||
}
|
||||
|
||||
void IrcManager::writeConnectionMessageReceived(Communi::IrcMessage *message)
|
||||
{
|
||||
switch (message->type()) {
|
||||
case Communi::IrcMessage::Type::Notice: {
|
||||
helper::IrcMessageHandler::getInstance().handleWriteConnectionNoticeMessage(
|
||||
static_cast<Communi::IrcNoticeMessage *>(message));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: This does not fit in IrcManager
|
||||
bool IrcManager::isTwitchUserBlocked(QString const &username)
|
||||
{
|
||||
QMutexLocker locker(&this->twitchBlockedUsersMutex);
|
||||
|
||||
auto iterator = this->twitchBlockedUsers.find(username);
|
||||
|
||||
return iterator != this->twitchBlockedUsers.end();
|
||||
}
|
||||
|
||||
// XXX: This does not fit in IrcManager
|
||||
bool IrcManager::tryAddIgnoredUser(QString const &username, QString &errorMessage)
|
||||
{
|
||||
assert(this->account);
|
||||
|
||||
QUrl url("https://api.twitch.tv/kraken/users/" + this->account->getUserName() + "/blocks/" +
|
||||
username + "?oauth_token=" + this->account->getOAuthToken() +
|
||||
"&client_id=" + this->account->getOAuthClient());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
auto reply = this->networkAccessManager.put(request, QByteArray());
|
||||
reply->waitForReadyRead(10000);
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
this->twitchBlockedUsersMutex.lock();
|
||||
this->twitchBlockedUsers.insert(username, true);
|
||||
this->twitchBlockedUsersMutex.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
errorMessage = "Error while ignoring user \"" + username + "\": " + reply->errorString();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: This does not fit in IrcManager
|
||||
void IrcManager::addIgnoredUser(QString const &username)
|
||||
{
|
||||
QString errorMessage;
|
||||
if (!tryAddIgnoredUser(username, errorMessage)) {
|
||||
// TODO: Implement IrcManager::addIgnoredUser
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: This does not fit in IrcManager
|
||||
bool IrcManager::tryRemoveIgnoredUser(QString const &username, QString &errorMessage)
|
||||
{
|
||||
assert(this->account);
|
||||
|
||||
QUrl url("https://api.twitch.tv/kraken/users/" + this->account->getUserName() + "/blocks/" +
|
||||
username + "?oauth_token=" + this->account->getOAuthToken() +
|
||||
"&client_id=" + this->account->getOAuthClient());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
auto reply = this->networkAccessManager.deleteResource(request);
|
||||
reply->waitForReadyRead(10000);
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
this->twitchBlockedUsersMutex.lock();
|
||||
this->twitchBlockedUsers.remove(username);
|
||||
this->twitchBlockedUsersMutex.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
errorMessage = "Error while unignoring user \"" + username + "\": " + reply->errorString();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: This does not fit in IrcManager
|
||||
void IrcManager::removeIgnoredUser(QString const &username)
|
||||
{
|
||||
QString errorMessage;
|
||||
if (!tryRemoveIgnoredUser(username, errorMessage)) {
|
||||
// TODO: Implement IrcManager::removeIgnoredUser
|
||||
}
|
||||
}
|
||||
|
||||
void IrcManager::onConnected()
|
||||
{
|
||||
MessagePtr connMsg = Message::createSystemMessage("connected to chat");
|
||||
MessagePtr reconnMsg = Message::createSystemMessage("reconnected to chat");
|
||||
|
||||
this->channelManager.doOnAll([connMsg, reconnMsg](ChannelPtr channel) {
|
||||
assert(channel);
|
||||
|
||||
LimitedQueueSnapshot<MessagePtr> snapshot = channel->getMessageSnapshot();
|
||||
|
||||
bool replaceMessage =
|
||||
snapshot.getLength() > 0 &&
|
||||
snapshot[snapshot.getLength() - 1]->flags & Message::DisconnectedMessage;
|
||||
|
||||
if (replaceMessage) {
|
||||
channel->replaceMessage(snapshot[snapshot.getLength() - 1], reconnMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
channel->addMessage(connMsg);
|
||||
});
|
||||
}
|
||||
|
||||
void IrcManager::onDisconnected()
|
||||
{
|
||||
MessagePtr msg = Message::createSystemMessage("disconnected from chat");
|
||||
msg->flags &= Message::DisconnectedMessage;
|
||||
|
||||
this->channelManager.doOnAll([msg](ChannelPtr channel) {
|
||||
assert(channel);
|
||||
channel->addMessage(msg);
|
||||
});
|
||||
}
|
||||
|
||||
Communi::IrcConnection *IrcManager::getReadConnection()
|
||||
{
|
||||
return this->readConnection.get();
|
||||
}
|
||||
|
||||
void IrcManager::addFakeMessage(const QString &data)
|
||||
{
|
||||
auto fakeMessage = Communi::IrcMessage::fromData(data.toUtf8(), this->readConnection.get());
|
||||
|
||||
this->privateMessageReceived(qobject_cast<Communi::IrcPrivateMessage *>(fakeMessage));
|
||||
}
|
||||
|
||||
} // namespace singletons
|
||||
} // namespace chatterino
|
||||
// void IrcManager::refreshIgnoredUsers(const QString &username, const QString &oauthClient,
|
||||
// const QString &oauthToken)
|
||||
//{
|
||||
// QString nextLink = "https://api.twitch.tv/kraken/users/" + username + "/blocks?limit=" + 100 +
|
||||
// "&client_id=" + oauthClient;
|
||||
//
|
||||
// QNetworkAccessManager *manager = new QNetworkAccessManager();
|
||||
// QNetworkRequest req(QUrl(nextLink + "&oauth_token=" + oauthToken));
|
||||
// QNetworkReply *reply = manager->get(req);
|
||||
//
|
||||
// QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||
// this->twitchBlockedUsersMutex.lock();
|
||||
// this->twitchBlockedUsers.clear();
|
||||
// this->twitchBlockedUsersMutex.unlock();
|
||||
//
|
||||
// QByteArray data = reply->readAll();
|
||||
// QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
// QJsonObject root = jsonDoc.object();
|
||||
//
|
||||
// // nextLink =
|
||||
// // root.value("this->links").toObject().value("next").toString();
|
||||
//
|
||||
// auto blocks = root.value("blocks").toArray();
|
||||
//
|
||||
// this->twitchBlockedUsersMutex.lock();
|
||||
// for (QJsonValue block : blocks) {
|
||||
// QJsonObject user = block.toObject().value("user").toObject();
|
||||
// // displaythis->name
|
||||
// this->twitchBlockedUsers.insert(user.value("name").toString().toLower(), true);
|
||||
// }
|
||||
// this->twitchBlockedUsersMutex.unlock();
|
||||
//
|
||||
// manager->deleteLater();
|
||||
// });
|
||||
//}
|
||||
//
|
||||
//// XXX: This does not fit in IrcManager
|
||||
// bool IrcManager::isTwitchUserBlocked(QString const &username)
|
||||
//{
|
||||
// QMutexLocker locker(&this->twitchBlockedUsersMutex);
|
||||
//
|
||||
// auto iterator = this->twitchBlockedUsers.find(username);
|
||||
//
|
||||
// return iterator != this->twitchBlockedUsers.end();
|
||||
//}
|
||||
//
|
||||
//// XXX: This does not fit in IrcManager
|
||||
// bool IrcManager::tryAddIgnoredUser(QString const &username, QString &errorMessage)
|
||||
//{
|
||||
// assert(this->account);
|
||||
//
|
||||
// QUrl url("https://api.twitch.tv/kraken/users/" + this->account->getUserName() + "/blocks/" +
|
||||
// username + "?oauth_token=" + this->account->getOAuthToken() +
|
||||
// "&client_id=" + this->account->getOAuthClient());
|
||||
//
|
||||
// QNetworkRequest request(url);
|
||||
// auto reply = this->networkAccessManager.put(request, QByteArray());
|
||||
// reply->waitForReadyRead(10000);
|
||||
//
|
||||
// if (reply->error() == QNetworkReply::NoError) {
|
||||
// this->twitchBlockedUsersMutex.lock();
|
||||
// this->twitchBlockedUsers.insert(username, true);
|
||||
// this->twitchBlockedUsersMutex.unlock();
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// reply->deleteLater();
|
||||
//
|
||||
// errorMessage = "Error while ignoring user \"" + username + "\": " + reply->errorString();
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//// XXX: This does not fit in IrcManager
|
||||
// void IrcManager::addIgnoredUser(QString const &username)
|
||||
//{
|
||||
// QString errorMessage;
|
||||
// if (!tryAddIgnoredUser(username, errorMessage)) {
|
||||
// // TODO: Implement IrcManager::addIgnoredUser
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// XXX: This does not fit in IrcManager
|
||||
// bool IrcManager::tryRemoveIgnoredUser(QString const &username, QString &errorMessage)
|
||||
//{
|
||||
// assert(this->account);
|
||||
//
|
||||
// QUrl url("https://api.twitch.tv/kraken/users/" + this->account->getUserName() + "/blocks/" +
|
||||
// username + "?oauth_token=" + this->account->getOAuthToken() +
|
||||
// "&client_id=" + this->account->getOAuthClient());
|
||||
//
|
||||
// QNetworkRequest request(url);
|
||||
// auto reply = this->networkAccessManager.deleteResource(request);
|
||||
// reply->waitForReadyRead(10000);
|
||||
//
|
||||
// if (reply->error() == QNetworkReply::NoError) {
|
||||
// this->twitchBlockedUsersMutex.lock();
|
||||
// this->twitchBlockedUsers.remove(username);
|
||||
// this->twitchBlockedUsersMutex.unlock();
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// reply->deleteLater();
|
||||
//
|
||||
// errorMessage = "Error while unignoring user \"" + username + "\": " + reply->errorString();
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//// XXX: This does not fit in IrcManager
|
||||
// void IrcManager::removeIgnoredUser(QString const &username)
|
||||
//{
|
||||
// QString errorMessage;
|
||||
// if (!tryRemoveIgnoredUser(username, errorMessage)) {
|
||||
// // TODO: Implement IrcManager::removeIgnoredUser
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -1,95 +1,13 @@
|
|||
#pragma once
|
||||
// bool isTwitchUserBlocked(QString const &username);
|
||||
// bool tryAddIgnoredUser(QString const &username, QString &errorMessage);
|
||||
// void addIgnoredUser(QString const &username);
|
||||
// bool tryRemoveIgnoredUser(QString const &username, QString &errorMessage);
|
||||
// void removeIgnoredUser(QString const &username);
|
||||
|
||||
#define TWITCH_MAX_MESSAGELENGTH 500
|
||||
// QMap<QString, bool> twitchBlockedUsers;
|
||||
// QMutex twitchBlockedUsersMutex;
|
||||
|
||||
#include "messages/message.hpp"
|
||||
#include "twitch/twitchuser.hpp"
|
||||
// QNetworkAccessManager networkAccessManager;
|
||||
|
||||
#include <ircconnection.h>
|
||||
#include <IrcMessage>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QString>
|
||||
#include <pajlada/signals/signal.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace chatterino {
|
||||
namespace singletons {
|
||||
|
||||
class ChannelManager;
|
||||
class ResourceManager;
|
||||
class AccountManager;
|
||||
class WindowManager;
|
||||
|
||||
class IrcManager : public QObject
|
||||
{
|
||||
IrcManager(ChannelManager &channelManager, ResourceManager &resources,
|
||||
AccountManager &accountManager);
|
||||
|
||||
public:
|
||||
static IrcManager &getInstance();
|
||||
|
||||
void connect();
|
||||
void disconnect();
|
||||
|
||||
bool isTwitchUserBlocked(QString const &username);
|
||||
bool tryAddIgnoredUser(QString const &username, QString &errorMessage);
|
||||
void addIgnoredUser(QString const &username);
|
||||
bool tryRemoveIgnoredUser(QString const &username, QString &errorMessage);
|
||||
void removeIgnoredUser(QString const &username);
|
||||
|
||||
void sendMessage(const QString &channelName, QString message);
|
||||
|
||||
void joinChannel(const QString &channelName);
|
||||
void partChannel(const QString &channelName);
|
||||
|
||||
void setUser(std::shared_ptr<twitch::TwitchUser> newAccount);
|
||||
|
||||
pajlada::Signals::Signal<Communi::IrcPrivateMessage *> onPrivateMessage;
|
||||
void privateMessageReceived(Communi::IrcPrivateMessage *message);
|
||||
boost::signals2::signal<void()> connected;
|
||||
|
||||
Communi::IrcConnection *getReadConnection();
|
||||
|
||||
/// Debug function
|
||||
void addFakeMessage(const QString &data);
|
||||
|
||||
private:
|
||||
ChannelManager &channelManager;
|
||||
ResourceManager &resources;
|
||||
AccountManager &accountManager;
|
||||
|
||||
// variables
|
||||
std::shared_ptr<twitch::TwitchUser> account = nullptr;
|
||||
|
||||
std::unique_ptr<Communi::IrcConnection> writeConnection = nullptr;
|
||||
std::unique_ptr<Communi::IrcConnection> readConnection = nullptr;
|
||||
|
||||
std::mutex connectionMutex;
|
||||
|
||||
QMap<QString, bool> twitchBlockedUsers;
|
||||
QMutex twitchBlockedUsersMutex;
|
||||
|
||||
QNetworkAccessManager networkAccessManager;
|
||||
|
||||
void initializeConnection(const std::unique_ptr<Communi::IrcConnection> &connection,
|
||||
bool isReadConnection);
|
||||
|
||||
void refreshIgnoredUsers(const QString &username, const QString &oauthClient,
|
||||
const QString &oauthToken);
|
||||
|
||||
void beginConnecting();
|
||||
|
||||
void messageReceived(Communi::IrcMessage *message);
|
||||
|
||||
void writeConnectionMessageReceived(Communi::IrcMessage *message);
|
||||
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
};
|
||||
|
||||
} // namespace singletons
|
||||
} // namespace chatterino
|
||||
// void refreshIgnoredUsers(const QString &username, const QString &oauthClient,
|
||||
// const QString &oauthToken);
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
#include "twitchuser.hpp"
|
||||
#include "const.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace twitch {
|
||||
|
||||
TwitchUser::TwitchUser(const QString &username, const QString &oauthToken,
|
||||
const QString &oauthClient)
|
||||
: IrcUser2(username, username, username, "oauth:" + oauthToken)
|
||||
, _oauthClient(oauthClient)
|
||||
, _oauthToken(oauthToken)
|
||||
, _isAnon(username == ANONYMOUS_USERNAME)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &TwitchUser::getOAuthClient() const
|
||||
{
|
||||
return this->_oauthClient;
|
||||
}
|
||||
|
||||
const QString &TwitchUser::getOAuthToken() const
|
||||
{
|
||||
return this->_oauthToken;
|
||||
}
|
||||
|
||||
const QString &TwitchUser::getUserId() const
|
||||
{
|
||||
return this->_userId;
|
||||
}
|
||||
|
||||
void TwitchUser::setUserId(const QString &id)
|
||||
{
|
||||
this->_userId = id;
|
||||
}
|
||||
|
||||
bool TwitchUser::setOAuthClient(const QString &newClientID)
|
||||
{
|
||||
if (this->_oauthClient.compare(newClientID) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->_oauthClient = newClientID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwitchUser::setOAuthToken(const QString &newOAuthToken)
|
||||
{
|
||||
if (this->_oauthToken.compare(newOAuthToken) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->_oauthToken = newOAuthToken;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwitchUser::isAnon() const
|
||||
{
|
||||
return this->_isAnon;
|
||||
}
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace chatterino
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#define async_exec(a) QThreadPool::globalInstance()->start(new LambdaRunnable(a));
|
||||
|
||||
namespace chatterino {
|
||||
namespace util {
|
||||
class LambdaRunnable : public QRunnable
|
||||
{
|
||||
public:
|
||||
|
@ -52,3 +54,5 @@ static void postToThread(F &&fun, QObject *obj = qApp)
|
|||
};
|
||||
QCoreApplication::postEvent(obj, new Event(std::forward<F>(fun)));
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "basewindow.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
#include "util/concurrentmap.hpp"
|
||||
|
||||
#include <QPushButton>
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
#include <QTabWidget>
|
||||
|
||||
#include "messages/messagebuilder.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
|
||||
using namespace chatterino::twitch;
|
||||
using namespace chatterino::providers::twitch;
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "messages/layouts/messagelayout.hpp"
|
||||
#include "messages/limitedqueuesnapshot.hpp"
|
||||
#include "messages/message.hpp"
|
||||
#include "providers/twitch/twitchserver.hpp"
|
||||
#include "singletons/channelmanager.hpp"
|
||||
#include "singletons/settingsmanager.hpp"
|
||||
#include "singletons/thememanager.hpp"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#define LAYOUT_WIDTH (this->width() - (this->scrollBar.isVisible() ? 16 : 4) * this->getScale())
|
||||
|
||||
using namespace chatterino::messages;
|
||||
using namespace chatterino::providers::twitch;
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
@ -35,7 +37,7 @@ namespace widgets {
|
|||
ChannelView::ChannelView(BaseWidget *parent)
|
||||
: BaseWidget(parent)
|
||||
, scrollBar(this)
|
||||
, userPopupWidget(std::shared_ptr<twitch::TwitchChannel>())
|
||||
, userPopupWidget(std::shared_ptr<TwitchChannel>())
|
||||
{
|
||||
#ifndef Q_OS_MAC
|
||||
// this->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
@ -476,7 +478,7 @@ messages::MessageElement::Flags ChannelView::getFlags() const
|
|||
if (split->getModerationMode()) {
|
||||
flags = (MessageElement::Flags)(flags | MessageElement::ModeratorTools);
|
||||
}
|
||||
if (this->channel == singletons::ChannelManager::getInstance().mentionsChannel) {
|
||||
if (this->channel == TwitchServer::getInstance().mentionsChannel) {
|
||||
flags = (MessageElement::Flags)(flags | MessageElement::ChannelName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "widgets/helper/resizingtextedit.hpp"
|
||||
#include "common.hpp"
|
||||
#include "singletons/completionmanager.hpp"
|
||||
|
||||
ResizingTextEdit::ResizingTextEdit()
|
||||
|
@ -79,13 +80,17 @@ void ResizingTextEdit::keyPressEvent(QKeyEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Tab &&
|
||||
(event->modifiers() & Qt::ControlModifier) == Qt::NoModifier) {
|
||||
bool doComplete =
|
||||
event->key() == Qt::Key_Tab && (event->modifiers() & Qt::ControlModifier) == Qt::NoModifier;
|
||||
|
||||
if (doComplete) {
|
||||
// check if there is a completer
|
||||
return_if_not(this->completer);
|
||||
|
||||
QString currentCompletionPrefix = this->textUnderCursor();
|
||||
|
||||
if (!currentCompletionPrefix.size()) {
|
||||
return;
|
||||
}
|
||||
// check if there is something to complete
|
||||
return_if_not(currentCompletionPrefix.size());
|
||||
|
||||
auto *completionModel =
|
||||
static_cast<chatterino::singletons::CompletionModel *>(this->completer->model());
|
||||
|
@ -109,6 +114,7 @@ void ResizingTextEdit::keyPressEvent(QKeyEvent *event)
|
|||
this->completer->complete();
|
||||
return;
|
||||
}
|
||||
|
||||
// (hemirt)
|
||||
// this resets the selection in the completion list, it should probably only trigger on actual
|
||||
// chat input (space, character) and not on every key input (pressing alt for example)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "widgets/helper/splitheader.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
#include "providers/twitch/twitchserver.hpp"
|
||||
#include "singletons/resourcemanager.hpp"
|
||||
#include "singletons/thememanager.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "util/layoutcreator.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
#include "widgets/helper/label.hpp"
|
||||
|
@ -18,6 +19,8 @@
|
|||
#include "widgets/streamview.hpp"
|
||||
#endif
|
||||
|
||||
using namespace chatterino::providers::twitch;
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
|
@ -98,7 +101,7 @@ void SplitHeader::addDropdownItems(RippleEffectButton *label)
|
|||
#ifdef USEWEBENGINE
|
||||
this->dropdownMenu.addAction("Start watching", this, [this]{
|
||||
ChannelPtr _channel = this->split->getChannel();
|
||||
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_channel.get());
|
||||
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
|
||||
|
||||
if (tc != nullptr) {
|
||||
StreamView *view = new StreamView(_channel, "https://player.twitch.tv/?channel=" + tc->name);
|
||||
|
@ -128,7 +131,7 @@ void SplitHeader::initializeChannelSignals()
|
|||
this->onlineStatusChangedConnection.disconnect();
|
||||
|
||||
auto channel = this->split->getChannel();
|
||||
twitch::TwitchChannel *twitchChannel = dynamic_cast<twitch::TwitchChannel *>(channel.get());
|
||||
TwitchChannel *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
||||
|
||||
if (twitchChannel) {
|
||||
twitchChannel->onlineStatusChanged.connect([this]() {
|
||||
|
@ -150,13 +153,13 @@ void SplitHeader::scaleChangedEvent(float scale)
|
|||
|
||||
void SplitHeader::updateChannelText()
|
||||
{
|
||||
const std::string channelName = this->split->channelName;
|
||||
if (channelName.empty()) {
|
||||
const QString channelName = this->split->channelName;
|
||||
if (channelName.isEmpty()) {
|
||||
this->titleLabel->setText("<no channel>");
|
||||
} else {
|
||||
auto channel = this->split->getChannel();
|
||||
|
||||
twitch::TwitchChannel *twitchChannel = dynamic_cast<twitch::TwitchChannel *>(channel.get());
|
||||
TwitchChannel *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
||||
|
||||
if (twitchChannel != nullptr && twitchChannel->isLive) {
|
||||
this->isLive = true;
|
||||
|
@ -169,10 +172,10 @@ void SplitHeader::updateChannelText()
|
|||
twitchChannel->streamViewerCount +
|
||||
" viewers"
|
||||
"</p>";
|
||||
this->titleLabel->setText(QString::fromStdString(channelName) + " (live)");
|
||||
this->titleLabel->setText(channelName + " (live)");
|
||||
} else {
|
||||
this->isLive = false;
|
||||
this->titleLabel->setText(QString::fromStdString(channelName));
|
||||
this->titleLabel->setText(channelName);
|
||||
this->tooltip = "";
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +191,7 @@ void SplitHeader::updateModerationModeIcon()
|
|||
bool modButtonVisible = false;
|
||||
ChannelPtr channel = this->split->getChannel();
|
||||
|
||||
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(channel.get());
|
||||
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(channel.get());
|
||||
|
||||
if (tc != nullptr && tc->hasModRights()) {
|
||||
modButtonVisible = true;
|
||||
|
@ -268,7 +271,8 @@ void SplitHeader::menuReloadChannelEmotes()
|
|||
|
||||
void SplitHeader::menuManualReconnect()
|
||||
{
|
||||
singletons::IrcManager::getInstance().connect();
|
||||
// fourtf: connection
|
||||
providers::twitch::TwitchServer::getInstance().connect();
|
||||
}
|
||||
|
||||
void SplitHeader::menuShowChangelog()
|
||||
|
|
|
@ -24,8 +24,8 @@ namespace widgets {
|
|||
|
||||
Notebook::Notebook(Window *parent, bool _showButtons, const std::string &settingPrefix)
|
||||
: BaseWidget(parent)
|
||||
, parentWindow(parent)
|
||||
, settingRoot(fS("{}/notebook", settingPrefix))
|
||||
, parentWindow(parent)
|
||||
, addButton(this)
|
||||
, settingsButton(this)
|
||||
, userButton(this)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include "widgets/split.hpp"
|
||||
#include "providers/twitch/emotevalue.hpp"
|
||||
#include "providers/twitch/twitchchannel.hpp"
|
||||
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||
#include "providers/twitch/twitchserver.hpp"
|
||||
#include "singletons/channelmanager.hpp"
|
||||
#include "singletons/settingsmanager.hpp"
|
||||
#include "singletons/thememanager.hpp"
|
||||
#include "singletons/windowmanager.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "twitch/twitchmessagebuilder.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
#include "widgets/helper/searchpopup.hpp"
|
||||
#include "widgets/helper/shortcut.hpp"
|
||||
|
@ -34,6 +36,7 @@
|
|||
#include <functional>
|
||||
#include <random>
|
||||
|
||||
using namespace chatterino::providers::twitch;
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
|
@ -45,7 +48,7 @@ Split::Split(SplitContainer *parent, const std::string &_uuid)
|
|||
, settingRoot(fS("/splits/{}", this->uuid))
|
||||
, channelName(fS("{}/channelName", this->settingRoot))
|
||||
, parentPage(*parent)
|
||||
, channel(singletons::ChannelManager::getInstance().emptyChannel)
|
||||
, channel(Channel::getEmpty())
|
||||
, vbox(this)
|
||||
, header(this)
|
||||
, view(this)
|
||||
|
@ -122,7 +125,6 @@ Split::Split(SplitContainer *parent, const std::string &_uuid)
|
|||
|
||||
Split::~Split()
|
||||
{
|
||||
this->channelNameUpdated("");
|
||||
this->usermodeChangedConnection.disconnect();
|
||||
this->channelIDChangedConnection.disconnect();
|
||||
}
|
||||
|
@ -150,7 +152,7 @@ void Split::setChannel(ChannelPtr _newChannel)
|
|||
|
||||
this->channel = _newChannel;
|
||||
|
||||
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_newChannel.get());
|
||||
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_newChannel.get());
|
||||
|
||||
if (tc != nullptr) {
|
||||
this->usermodeChangedConnection =
|
||||
|
@ -198,20 +200,13 @@ bool Split::getModerationMode() const
|
|||
return this->moderationMode;
|
||||
}
|
||||
|
||||
void Split::channelNameUpdated(const std::string &newChannelName)
|
||||
void Split::channelNameUpdated(const QString &newChannelName)
|
||||
{
|
||||
auto &cman = singletons::ChannelManager::getInstance();
|
||||
|
||||
// remove current channel
|
||||
if (!this->channel->isEmpty()) {
|
||||
cman.removeTwitchChannel(this->channel->name);
|
||||
}
|
||||
|
||||
// update messages
|
||||
if (newChannelName.empty()) {
|
||||
this->setChannel(cman.emptyChannel);
|
||||
if (newChannelName.isEmpty()) {
|
||||
this->setChannel(Channel::getEmpty());
|
||||
} else {
|
||||
this->setChannel(cman.addTwitchChannel(QString::fromStdString(newChannelName)));
|
||||
this->setChannel(TwitchServer::getInstance().addChannel(newChannelName));
|
||||
}
|
||||
|
||||
// update header
|
||||
|
@ -226,13 +221,13 @@ bool Split::showChangeChannelPopup(const char *dialogTitle, bool empty)
|
|||
dialog.setWindowTitle(dialogTitle);
|
||||
|
||||
if (!empty) {
|
||||
dialog.setText(QString::fromStdString(this->channelName));
|
||||
dialog.setText(this->channelName);
|
||||
}
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QString newChannelName = dialog.getText().trimmed();
|
||||
|
||||
this->channelName = newChannelName.toStdString();
|
||||
this->channelName = newChannelName;
|
||||
this->parentPage.refreshTitle();
|
||||
|
||||
return true;
|
||||
|
@ -355,7 +350,7 @@ void Split::doClearChat()
|
|||
void Split::doOpenChannel()
|
||||
{
|
||||
ChannelPtr _channel = this->channel;
|
||||
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_channel.get());
|
||||
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
|
||||
|
||||
if (tc != nullptr) {
|
||||
QDesktopServices::openUrl("https://twitch.tv/" + tc->name);
|
||||
|
@ -365,7 +360,7 @@ void Split::doOpenChannel()
|
|||
void Split::doOpenPopupPlayer()
|
||||
{
|
||||
ChannelPtr _channel = this->channel;
|
||||
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_channel.get());
|
||||
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
|
||||
|
||||
if (tc != nullptr) {
|
||||
QDesktopServices::openUrl("https://player.twitch.tv/?channel=" + tc->name);
|
||||
|
@ -379,7 +374,7 @@ void Split::doOpenStreamlink()
|
|||
preferredQuality = preferredQuality.toLower();
|
||||
// TODO(Confuseh): Default streamlink paths
|
||||
QString path = settings.streamlinkPath;
|
||||
QString channel = QString::fromStdString(this->channelName.getValue());
|
||||
QString channel = this->channelName.getValue();
|
||||
QFileInfo fileinfo = QFileInfo(path);
|
||||
|
||||
if (path.isEmpty()) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "messages/layouts/messagelayoutelement.hpp"
|
||||
#include "messages/limitedqueuesnapshot.hpp"
|
||||
#include "messages/messageelement.hpp"
|
||||
#include "util/serialize-custom.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/helper/channelview.hpp"
|
||||
#include "widgets/helper/rippleeffectlabel.hpp"
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
Split(SplitContainer *parent, const std::string &_uuid);
|
||||
virtual ~Split();
|
||||
|
||||
pajlada::Settings::Setting<std::string> channelName;
|
||||
pajlada::Settings::Setting<QString> channelName;
|
||||
boost::signals2::signal<void()> channelChanged;
|
||||
|
||||
ChannelView &getChannelView()
|
||||
|
@ -99,7 +100,7 @@ private:
|
|||
|
||||
void setChannel(ChannelPtr newChannel);
|
||||
void doOpenAccountPopupWidget(AccountPopupWidget *widget, QString user);
|
||||
void channelNameUpdated(const std::string &newChannelName);
|
||||
void channelNameUpdated(const QString &newChannelName);
|
||||
void handleModifiers(QEvent *event, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -30,10 +30,9 @@ SplitContainer::SplitContainer(Notebook *parent, NotebookTab *_tab, const std::s
|
|||
: BaseWidget(parent->themeManager, parent)
|
||||
, uuid(_uuid)
|
||||
, settingRoot(fS("/containers/{}", this->uuid))
|
||||
, chats(fS("{}/chats", this->settingRoot))
|
||||
, tab(_tab)
|
||||
, chats(fS("{}/chats", this->settingRoot))
|
||||
, dropPreview(this)
|
||||
, splits()
|
||||
{
|
||||
this->tab->page = this;
|
||||
|
||||
|
@ -468,8 +467,7 @@ void SplitContainer::refreshTitle()
|
|||
bool first = true;
|
||||
|
||||
for (const auto &chatWidget : this->splits) {
|
||||
auto channelName = QString::fromStdString(chatWidget->channelName.getValue());
|
||||
|
||||
auto channelName = chatWidget->channelName.getValue();
|
||||
if (channelName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
|
|||
, settingRoot(fS("/windows/{}", windowName))
|
||||
, windowGeometry(this->settingRoot)
|
||||
, dpi(this->getScale())
|
||||
, themeManager(_themeManager)
|
||||
, notebook(this, _isMainWindow, this->settingRoot)
|
||||
{
|
||||
singletons::AccountManager::getInstance().Twitch.currentUsername.connect(
|
||||
|
@ -98,11 +97,11 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
|
|||
cheerMessages.emplace_back(R"(@badges=subscriber/3,premium/1;bits=1;color=#FF0000;display-name=kalvarenga;emotes=;id=4744d6f0-de1d-475d-a3ff-38647113265a;mod=0;room-id=11148817;subscriber=1;tmi-sent-ts=1515782860740;turbo=0;user-id=108393131;user-type= :kalvarenga!kalvarenga@kalvarenga.tmi.twitch.tv PRIVMSG #pajlada :trihard1)");
|
||||
// clang-format on
|
||||
|
||||
CreateWindowShortcut(this, "F5", [cheerMessages] {
|
||||
auto &ircManager = singletons::IrcManager::getInstance();
|
||||
static int index = 0;
|
||||
ircManager.addFakeMessage(cheerMessages[index++ % cheerMessages.size()]);
|
||||
});
|
||||
// CreateWindowShortcut(this, "F5", [cheerMessages] {
|
||||
// auto &ircManager = singletons::IrcManager::getInstance();
|
||||
// static int index = 0;
|
||||
// ircManager.addFakeMessage(cheerMessages[index++ % cheerMessages.size()]);
|
||||
// });
|
||||
}
|
||||
|
||||
void Window::repaintVisibleChatWidgets(Channel *channel)
|
||||
|
|
|
@ -60,8 +60,6 @@ protected:
|
|||
virtual bool event(QEvent *event) override;
|
||||
|
||||
private:
|
||||
singletons::ThemeManager &themeManager;
|
||||
|
||||
float dpi;
|
||||
|
||||
void loadGeometry();
|
||||
|
|
Loading…
Reference in a new issue