diff --git a/browser_ext/.editorconfig b/browser_ext/.editorconfig
new file mode 100644
index 000000000..37346aa2f
--- /dev/null
+++ b/browser_ext/.editorconfig
@@ -0,0 +1,19 @@
+root = true
+
+[*]
+
+# Change these settings to your own preference
+indent_style = space
+indent_size = 2
+
+# We recommend you to keep these unchanged
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
\ No newline at end of file
diff --git a/browser_ext/background.js b/browser_ext/background.js
new file mode 100644
index 000000000..0de070118
--- /dev/null
+++ b/browser_ext/background.js
@@ -0,0 +1,66 @@
+const ignoredPages = {
+ "settings": true,
+ "payments": true,
+ "inventory": true,
+ "messages": true,
+ "subscriptions": true,
+ "friends": true,
+ "directory": true,
+};
+
+const appName = "com.chatterino.chatterino";
+
+function matchUrl(url) {
+ if (!url)
+ return;
+
+ const match = url.match(/^https?:\/\/(www\.)?twitch.tv\/([a-zA-Z0-9]+)\/?$/);
+
+ if (match) {
+ const channelName = match[2];
+
+ if (!ignoredPages[channelName]) {
+ selectChannel(channelName);
+ }
+ }
+}
+
+var port = chrome.runtime.connectNative("com.chatterino.chatterino");
+
+port.onMessage.addListener(function(msg) {
+ console.log(msg);
+});
+port.onDisconnect.addListener(function() {
+ console.log("Disconnected");
+});
+port.postMessage({ text: "Hello, my_application" });
+
+function selectChannel(channelName) {
+ console.log(channelName);
+
+ port.postMessage({channelName: channelName});
+
+ // chrome.runtime.sendNativeMessage(appName, { "xd": true }, (resp) => {
+ // console.log(resp);
+ // })
+}
+
+/// add listeners
+chrome.tabs.onActivated.addListener((activeInfo) => {
+ chrome.tabs.get(activeInfo.tabId, (tab) => {
+ if (!tab)
+ return;
+
+ if (!tab.url)
+ return;
+
+ matchUrl(tab.url);
+ });
+});
+
+chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
+ if (!tab.highlighted)
+ return;
+
+ matchUrl(changeInfo.url);
+});
diff --git a/browser_ext/icon.png b/browser_ext/icon.png
new file mode 100644
index 000000000..9a6f5ba19
Binary files /dev/null and b/browser_ext/icon.png differ
diff --git a/browser_ext/manifest.json b/browser_ext/manifest.json
new file mode 100644
index 000000000..74d9fae08
--- /dev/null
+++ b/browser_ext/manifest.json
@@ -0,0 +1,21 @@
+{
+ "name": "Chatterino",
+ "version": "1.0",
+ "description": "xd",
+ "permissions": [
+ "tabs", "nativeMessaging"
+ ],
+ "icons": {
+ "256": "icon.png"
+ },
+ "manifest_version": 2,
+ "background": {
+ "scripts": [
+ "background.js"
+ ],
+ "persistent": false
+ },
+ "browser_action": {
+ "default_popup": "popup.html"
+ }
+}
diff --git a/browser_ext/popup.html b/browser_ext/popup.html
new file mode 100644
index 000000000..e24ef44ab
--- /dev/null
+++ b/browser_ext/popup.html
@@ -0,0 +1,6 @@
+
+
+
+ xd
+
+
diff --git a/chatterino.pro b/chatterino.pro
index 4ab4b8e7a..0c234fb98 100644
--- a/chatterino.pro
+++ b/chatterino.pro
@@ -103,7 +103,6 @@ SOURCES += \
src/providers/twitch/twitchmessagebuilder.cpp \
src/providers/twitch/twitchserver.cpp \
src/singletons/accountmanager.cpp \
- src/singletons/channelmanager.cpp \
src/singletons/commandmanager.cpp \
src/singletons/emotemanager.cpp \
src/singletons/fontmanager.cpp \
@@ -171,7 +170,8 @@ SOURCES += \
src/providers/twitch/twitchhelpers.cpp \
src/widgets/helper/signallabel.cpp \
src/widgets/helper/debugpopup.cpp \
- src/util/debugcount.cpp
+ src/util/debugcount.cpp \
+ src/singletons/nativemessagingmanager.cpp
HEADERS += \
src/precompiled_header.hpp \
@@ -201,7 +201,6 @@ HEADERS += \
src/providers/twitch/twitchmessagebuilder.hpp \
src/providers/twitch/twitchserver.hpp \
src/singletons/accountmanager.hpp \
- src/singletons/channelmanager.hpp \
src/singletons/commandmanager.hpp \
src/singletons/emotemanager.hpp \
src/singletons/fontmanager.hpp \
@@ -212,7 +211,6 @@ HEADERS += \
src/singletons/loggingmanager.hpp \
src/singletons/pathmanager.hpp \
src/singletons/resourcemanager.hpp \
- src/singletons/settingsmanager.hpp \
src/singletons/thememanager.hpp \
src/singletons/windowmanager.hpp \
src/util/benchmark.hpp \
@@ -288,7 +286,9 @@ HEADERS += \
src/providers/twitch/twitchhelpers.hpp \
src/util/debugcount.hpp \
src/widgets/helper/debugpopup.hpp \
- src/version.hpp
+ src/version.hpp \
+ src/singletons/settingsmanager.hpp \
+ src/singletons/nativemessagingmanager.hpp
RESOURCES += \
resources/resources.qrc
diff --git a/src/application.cpp b/src/application.cpp
index fbd8dacb7..f29fbb837 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -4,6 +4,7 @@
#include "singletons/commandmanager.hpp"
#include "singletons/emotemanager.hpp"
#include "singletons/loggingmanager.hpp"
+#include "singletons/nativemessagingmanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp"
@@ -17,6 +18,8 @@ namespace chatterino {
Application::Application()
{
+ singletons::NativeMessagingManager::getInstance().registerHost();
+
singletons::WindowManager::getInstance();
singletons::LoggingManager::getInstance();
diff --git a/src/main.cpp b/src/main.cpp
index a170c00e6..2b6b4ed77 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3,7 +3,11 @@
#include
#include
+#include
#include
+#include
+
+#include
#include "util/networkmanager.hpp"
@@ -11,7 +15,37 @@
#include "util/nativeeventhelper.hpp"
#endif
+#include "fstream"
+
+#ifdef Q_OS_WIN
+#include "fcntl.h"
+#include "io.h"
+#include "stdio.h"
+#endif
+
+void runNativeMessagingHost();
+int runGui(int argc, char *argv[]);
+
int main(int argc, char *argv[])
+{
+ // read args
+ QStringList args;
+
+ for (int i = 1; i < argc; i++) {
+ args << argv[i];
+ }
+
+ // TODO: can be any argument
+ if (args.size() > 0 && args[0].startsWith("chrome-extension://")) {
+ runNativeMessagingHost();
+ return 0;
+ }
+
+ // run gui
+ return runGui(argc, argv);
+}
+
+int runGui(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_Use96Dpi, true);
#ifdef Q_OS_WIN32
@@ -55,3 +89,44 @@ int main(int argc, char *argv[])
_exit(0);
}
+
+void writeByteArray(QByteArray a)
+{
+ char *data = a.data();
+ uint32_t size;
+ size = a.size();
+ std::cout.write(reinterpret_cast(&size), 4);
+ std::cout.write(data, a.size());
+}
+
+void runNativeMessagingHost()
+{
+#ifdef Q_OS_WIN
+ _setmode(_fileno(stdin), _O_BINARY);
+ _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ // std::ofstream xd("C:\\users\\daniel\\desktop\\xd.lmao");
+
+ while (true) {
+ char size_c[4];
+ std::cin.read(size_c, 4);
+
+ if (std::cin.eof()) {
+ break;
+ }
+
+ uint32_t size = *reinterpret_cast(size_c);
+
+ char *b = (char *)malloc(size + 1);
+ std::cin.read(b, size);
+ *(b + size) = '\0';
+
+ // xd << b;
+ // xd.flush();
+
+ free(b);
+
+ // writeByteArray(QString("{\"xd\":1}").toUtf8());
+ }
+}
diff --git a/src/providers/twitch/twitchchannel.cpp b/src/providers/twitch/twitchchannel.cpp
index 8daa92d75..cdb16af8a 100644
--- a/src/providers/twitch/twitchchannel.cpp
+++ b/src/providers/twitch/twitchchannel.cpp
@@ -3,7 +3,6 @@
#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"
diff --git a/src/singletons/channelmanager.cpp b/src/singletons/channelmanager.cpp
deleted file mode 100644
index 45b27988f..000000000
--- a/src/singletons/channelmanager.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-//#include "singletons/channelmanager.hpp"
-//#include "singletons/ircmanager.hpp"
-
-// namespace chatterino {
-// namespace singletons {
-
-// ChannelManager &ChannelManager::getInstance()
-//{
-// static ChannelManager instance;
-// return instance;
-//}
-
-// ChannelManager::ChannelManager()
-// : whispersChannel(new Channel("/whispers"))
-// , mentionsChannel(new Channel("/mentions"))
-// , emptyChannel(new Channel(""))
-//{
-//}
-
-// const std::vector ChannelManager::getItems()
-//{
-// QMutexLocker locker(&this->channelsMutex);
-
-// std::vector items;
-
-// for (auto &item : this->twitchChannels.values()) {
-// items.push_back(std::get<0>(item));
-// }
-
-// return items;
-//}
-
-// ChannelPtr ChannelManager::addTwitchChannel(const QString &rawChannelName)
-//{
-// QString channelName = rawChannelName.toLower();
-
-// if (channelName.length() > 1 && channelName.at(0) == '/') {
-// return this->getTwitchChannel(channelName);
-// }
-
-// if (channelName.length() > 0 && channelName.at(0) == '#') {
-// channelName = channelName.mid(1);
-// }
-
-// QMutexLocker locker(&this->channelsMutex);
-
-// auto it = this->twitchChannels.find(channelName);
-
-// if (it == this->twitchChannels.end()) {
-// auto channel = std::make_shared(channelName);
-
-// this->twitchChannels.insert(channelName, std::make_tuple(channel, 1));
-
-// this->ircJoin.invoke(channelName);
-
-// return channel;
-// }
-
-// std::get<1>(it.value())++;
-
-// return std::get<0>(it.value());
-//}
-
-// ChannelPtr ChannelManager::getTwitchChannel(const QString &channel)
-//{
-// QMutexLocker locker(&this->channelsMutex);
-
-// QString c = channel.toLower();
-
-// if (channel.length() > 1 && channel.at(0) == '/') {
-// if (c == "/whispers") {
-// return whispersChannel;
-// }
-
-// if (c == "/mentions") {
-// return mentionsChannel;
-// }
-
-// return emptyChannel;
-// }
-
-// auto a = this->twitchChannels.find(c);
-
-// if (a == this->twitchChannels.end()) {
-// return emptyChannel;
-// }
-
-// return std::get<0>(a.value());
-//}
-
-// void ChannelManager::removeTwitchChannel(const QString &channel)
-//{
-// QMutexLocker locker(&this->channelsMutex);
-
-// if (channel.length() > 1 && channel.at(0) == '/') {
-// return;
-// }
-
-// QString c = channel.toLower();
-
-// auto a = this->twitchChannels.find(c);
-
-// if (a == this->twitchChannels.end()) {
-// return;
-// }
-
-// std::get<1>(a.value())--;
-
-// 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);
-
-// if (it != std::end(this->usernameToID)) {
-// return *it;
-// }
-// */
-
-// static std::string temporary = "xd";
-// return temporary;
-//}
-
-// void ChannelManager::doOnAll(std::function func)
-//{
-// for (const auto &channel : this->twitchChannels) {
-// func(std::get<0>(channel));
-// }
-
-// func(this->whispersChannel);
-// func(this->mentionsChannel);
-//}
-
-//}
-
-// void ChannelManager::doOnAllNormalChannels(std::function func)
-//{
-// for (const auto &channel : this->twitchChannels) {
-// func(std::get<0>(channel));
-// }
-//}
-
-//} // namespace chatterino
-//}
diff --git a/src/singletons/channelmanager.hpp b/src/singletons/channelmanager.hpp
deleted file mode 100644
index ff92f56f8..000000000
--- a/src/singletons/channelmanager.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//#pragma once
-
-//#include "channel.hpp"
-//#include "channeldata.hpp"
-//#include "providers/twitch/twitchchannel.hpp"
-
-//#include