mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
moved the browser extension into it's own repository
This commit is contained in:
parent
61a6accc54
commit
416b2d0d74
|
@ -1,19 +0,0 @@
|
||||||
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
|
|
|
@ -1,217 +0,0 @@
|
||||||
const ignoredPages = {
|
|
||||||
"settings": true,
|
|
||||||
"payments": true,
|
|
||||||
"inventory": true,
|
|
||||||
"messages": true,
|
|
||||||
"subscriptions": true,
|
|
||||||
"friends": true,
|
|
||||||
"directory": true,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// return channel name if it should contain a chat
|
|
||||||
function matchChannelName(url) {
|
|
||||||
if (!url)
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
const match = url.match(/^https?:\/\/(www\.)?twitch.tv\/([a-zA-Z0-9_]+)\/?$/);
|
|
||||||
|
|
||||||
let channelName;
|
|
||||||
if (match && (channelName = match[2], !ignoredPages[channelName])) {
|
|
||||||
return channelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const appName = "com.chatterino.chatterino";
|
|
||||||
let port = null;
|
|
||||||
|
|
||||||
// gets the port for communication with chatterino
|
|
||||||
function getPort() {
|
|
||||||
if (port) {
|
|
||||||
return port;
|
|
||||||
} else {
|
|
||||||
// TODO: add cooldown
|
|
||||||
connectPort();
|
|
||||||
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// connect to port
|
|
||||||
function connectPort() {
|
|
||||||
port = chrome.runtime.connectNative(appName);
|
|
||||||
console.log("port connected");
|
|
||||||
let connected = true;
|
|
||||||
|
|
||||||
port.onMessage.addListener(function (msg) {
|
|
||||||
console.log(msg);
|
|
||||||
});
|
|
||||||
port.onDisconnect.addListener(function () {
|
|
||||||
console.log("port disconnected");
|
|
||||||
|
|
||||||
port = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
let sendPing = () => {
|
|
||||||
if (connected) {
|
|
||||||
port.postMessage({ ping: true });
|
|
||||||
} else {
|
|
||||||
setTimeout(sendPing, 5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// tab activated
|
|
||||||
chrome.tabs.onActivated.addListener((activeInfo) => {
|
|
||||||
chrome.tabs.get(activeInfo.tabId, (tab) => {
|
|
||||||
if (!tab || !tab.url) return;
|
|
||||||
|
|
||||||
chrome.windows.get(tab.windowId, {}, (window) => {
|
|
||||||
if (!window.focused) return;
|
|
||||||
|
|
||||||
if (window.state == "fullscreen") {
|
|
||||||
tryDetach(tab.windowId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("onActivated");
|
|
||||||
onTabSelected(tab.url, tab);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// url changed
|
|
||||||
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
|
||||||
if (!tab.highlighted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
chrome.windows.get(tab.windowId, {}, (window) => {
|
|
||||||
if (!window.focused) return;
|
|
||||||
if (window.state == "fullscreen") {
|
|
||||||
tryDetach(tab.windowId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("onUpdated");
|
|
||||||
onTabSelected(tab.url, tab);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// tab detached
|
|
||||||
chrome.tabs.onDetached.addListener((tabId, detachInfo) => {
|
|
||||||
console.log("onDetached");
|
|
||||||
tryDetach(detachInfo.oldWindowId);
|
|
||||||
});
|
|
||||||
|
|
||||||
// tab closed
|
|
||||||
chrome.windows.onRemoved.addListener((windowId) => {
|
|
||||||
console.log("onRemoved");
|
|
||||||
tryDetach(windowId);
|
|
||||||
});
|
|
||||||
|
|
||||||
// window selected
|
|
||||||
chrome.windows.onFocusChanged.addListener((windowId) => {
|
|
||||||
console.log(windowId);
|
|
||||||
if (windowId == -1) return;
|
|
||||||
|
|
||||||
// this returns all tabs when the query fails
|
|
||||||
chrome.tabs.query({ windowId: windowId, highlighted: true }, (tabs) => {
|
|
||||||
if (tabs.length === 1) {
|
|
||||||
let tab = tabs[0];
|
|
||||||
|
|
||||||
chrome.windows.get(tab.windowId, (window) => {
|
|
||||||
if (window.state == "fullscreen") {
|
|
||||||
tryDetach(tab.windowId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("onFocusChanged");
|
|
||||||
onTabSelected(tab.url, tab);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// attach or detach from tab
|
|
||||||
function onTabSelected(url, tab) {
|
|
||||||
let channelName = matchChannelName(url);
|
|
||||||
|
|
||||||
if (channelName) {
|
|
||||||
// chrome.windows.get(tab.windowId, {}, (window) => {
|
|
||||||
// // attach to window
|
|
||||||
// tryAttach(tab.windowId, {
|
|
||||||
// name: channelName,
|
|
||||||
// yOffset: window.height - tab.height,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
} else {
|
|
||||||
// detach from window
|
|
||||||
tryDetach(tab.windowId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// receiving messages from the inject script
|
|
||||||
chrome.runtime.onMessage.addListener((message, sender, callback) => {
|
|
||||||
console.log(message);
|
|
||||||
|
|
||||||
// is tab highlighted
|
|
||||||
if (!sender.tab.highlighted) return;
|
|
||||||
|
|
||||||
// is window focused
|
|
||||||
chrome.windows.get(sender.tab.windowId, {}, (window) => {
|
|
||||||
if (!window.focused) return;
|
|
||||||
if (window.state == "fullscreen") {
|
|
||||||
tryDetach(sender.tab.windowId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get zoom value
|
|
||||||
chrome.tabs.getZoom(sender.tab.id, (zoom) => {
|
|
||||||
let size = {
|
|
||||||
width: Math.floor(message.rect.width * zoom),
|
|
||||||
height: Math.floor(message.rect.height * zoom),
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log(zoom);
|
|
||||||
|
|
||||||
// attach to window
|
|
||||||
tryAttach(sender.tab.windowId, {
|
|
||||||
name: matchChannelName(sender.tab.url),
|
|
||||||
size: size,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// attach chatterino to a chrome window
|
|
||||||
function tryAttach(windowId, data) {
|
|
||||||
data.action = "select";
|
|
||||||
data.attach = true;
|
|
||||||
data.type = "twitch";
|
|
||||||
data.winId = "" + windowId;
|
|
||||||
|
|
||||||
let port = getPort();
|
|
||||||
|
|
||||||
if (port) {
|
|
||||||
port.postMessage(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// detach chatterino from a chrome window
|
|
||||||
function tryDetach(windowId) {
|
|
||||||
let port = getPort();
|
|
||||||
|
|
||||||
console.log("tryDetach");
|
|
||||||
|
|
||||||
if (port) {
|
|
||||||
port.postMessage({
|
|
||||||
action: "detach",
|
|
||||||
winId: "" + windowId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
|
@ -1,180 +0,0 @@
|
||||||
(() => {
|
|
||||||
let lastRect = {};
|
|
||||||
let port = null;
|
|
||||||
|
|
||||||
let installedObjects = {};
|
|
||||||
let rightCollapseButton = null;
|
|
||||||
let isCollapsed = false;
|
|
||||||
|
|
||||||
const ignoredPages = {
|
|
||||||
"settings": true,
|
|
||||||
"payments": true,
|
|
||||||
"inventory": true,
|
|
||||||
"messages": true,
|
|
||||||
"subscriptions": true,
|
|
||||||
"friends": true,
|
|
||||||
"directory": true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let findChatDiv = () => document.getElementsByClassName("right-column")[0];
|
|
||||||
let findRightCollapse = () => document.getElementsByClassName("right-column__toggle-visibility")[0];
|
|
||||||
let findRightColumn = () => document.getElementsByClassName("channel-page__right-column")[0];
|
|
||||||
let findNavBar = () => document.getElementsByClassName("top-nav__menu")[0];
|
|
||||||
|
|
||||||
// logging function
|
|
||||||
function log(str) {
|
|
||||||
console.log("Chatterino Native: " + str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// install events
|
|
||||||
function installChatterino() {
|
|
||||||
log("trying to install events");
|
|
||||||
|
|
||||||
let retry = false;
|
|
||||||
|
|
||||||
// right collapse button
|
|
||||||
if (!installedObjects.rightCollapse) {
|
|
||||||
retry = true;
|
|
||||||
|
|
||||||
let x = findRightCollapse();
|
|
||||||
|
|
||||||
if (x != undefined) {
|
|
||||||
rightCollapseButton = x;
|
|
||||||
|
|
||||||
x.addEventListener("click", () => {
|
|
||||||
let y = findChatDiv();
|
|
||||||
|
|
||||||
if (parseInt(y.style.width) == 0) {
|
|
||||||
y.style.width = "340px";
|
|
||||||
isCollapsed = false;
|
|
||||||
} else {
|
|
||||||
y.style.width = 0;
|
|
||||||
isCollapsed = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
installedObjects.rightCollapse = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// right column
|
|
||||||
if (!installedObjects.rightColumn && installedObjects.rightCollapse) {
|
|
||||||
let x = findChatDiv();
|
|
||||||
|
|
||||||
if (x != undefined && x.children.length >= 2) {
|
|
||||||
x.children[0].innerHTML = "<div style='width: 340px; height: 100%; justify-content: center; display: flex; flex-direction: column; text-align: center; color: #999; user-select: none; background: #222;'>" +
|
|
||||||
"Disconnected from the chatterino extension.<br><br>Please focus the window or refresh the page." +
|
|
||||||
"</div>";
|
|
||||||
|
|
||||||
installedObjects.rightColumn = true;
|
|
||||||
} else {
|
|
||||||
retry = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// nav bar
|
|
||||||
if (!installedObjects.topNav) {
|
|
||||||
if (rightCollapseButton) {
|
|
||||||
let x = findNavBar();
|
|
||||||
|
|
||||||
x.addEventListener("mouseup", () => {
|
|
||||||
console.log(isCollapsed)
|
|
||||||
|
|
||||||
if (!isCollapsed) {
|
|
||||||
let collapse = findRightCollapse();
|
|
||||||
collapse.click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
installedObjects.topNav = true;
|
|
||||||
} else {
|
|
||||||
retry = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// retry if needed
|
|
||||||
if (retry) {
|
|
||||||
setTimeout(installChatterino, 1000);
|
|
||||||
} else {
|
|
||||||
log("installed all events");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// query the rect of the chat
|
|
||||||
function queryChatRect() {
|
|
||||||
if (!matchChannelName(window.location.href)) return;
|
|
||||||
|
|
||||||
let element = findChatDiv();
|
|
||||||
|
|
||||||
if (element === undefined) {
|
|
||||||
log("failed to find chat div");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let rect = element.getBoundingClientRect();
|
|
||||||
|
|
||||||
/* if (
|
|
||||||
lastRect.left == rect.left &&
|
|
||||||
lastRect.right == rect.right &&
|
|
||||||
lastRect.top == rect.top &&
|
|
||||||
lastRect.bottom == rect.bottom
|
|
||||||
) {
|
|
||||||
// log("skipped sending message");
|
|
||||||
return;
|
|
||||||
} */
|
|
||||||
lastRect = rect;
|
|
||||||
|
|
||||||
let data = {
|
|
||||||
rect: rect,
|
|
||||||
};
|
|
||||||
|
|
||||||
isCollapsed = rect.width == 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
chrome.runtime.sendMessage(data);
|
|
||||||
} catch {
|
|
||||||
// failed to send a message to the runtime -> maybe the extension got reloaded
|
|
||||||
// alert("reload the page to re-enable chatterino native");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function queryChatRectLoop() {
|
|
||||||
let t1 = performance.now();
|
|
||||||
queryChatRect();
|
|
||||||
let t2 = performance.now();
|
|
||||||
console.log("queryCharRect " + (t2 - t1) + "ms");
|
|
||||||
// setTimeout(queryCharRectLoop, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return channel name if it should contain a chat or undefined
|
|
||||||
function matchChannelName(url) {
|
|
||||||
if (!url)
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
const match = url.match(/^https?:\/\/(www\.)?twitch.tv\/([a-zA-Z0-9_]+)\/?$/);
|
|
||||||
|
|
||||||
let channelName;
|
|
||||||
if (match && (channelName = match[2], !ignoredPages[channelName])) {
|
|
||||||
return channelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// event listeners
|
|
||||||
window.addEventListener("load", () => setTimeout(queryChatRect, 1000));
|
|
||||||
window.addEventListener("resize", queryChatRect);
|
|
||||||
window.addEventListener("focus", queryChatRect);
|
|
||||||
window.addEventListener("mouseup", () => setTimeout(queryChatRect, 10));
|
|
||||||
window.addEventListener("hashchange", () => {
|
|
||||||
installedObjects = {};
|
|
||||||
installChatterino();
|
|
||||||
});
|
|
||||||
|
|
||||||
//
|
|
||||||
log("hello there in the dev tools 👋");
|
|
||||||
|
|
||||||
queryChatRectLoop();
|
|
||||||
installChatterino();
|
|
||||||
})()
|
|
|
@ -1,33 +0,0 @@
|
||||||
{
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
"content_scripts": [
|
|
||||||
{
|
|
||||||
"run_at": "document_end",
|
|
||||||
"matches": [
|
|
||||||
"https://www.twitch.tv/*"
|
|
||||||
],
|
|
||||||
"js": [
|
|
||||||
"inject.js"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
Chatterino extension :)
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
Loading…
Reference in a new issue