initial commit
This commit is contained in:
158
leetray/LeetRay.user.js
Normal file
158
leetray/LeetRay.user.js
Normal file
@@ -0,0 +1,158 @@
|
||||
// ==UserScript==
|
||||
// @name LeetRay
|
||||
// @namespace http://tampermonkey.net/
|
||||
// @version 0.1.1
|
||||
// @description Take beautiful screenshots of your code in Leetcode instantly with Ray.so
|
||||
// @updateURL https://git.sangeeth.dev/x/userscripts/raw/branch/main/leetray/LeetRay.user.js
|
||||
// @downloadURL https://git.sangeeth.dev/x/userscripts/raw/branch/main/leetray/LeetRay.user.js
|
||||
// @author Sangeeth Sudheer
|
||||
// @match https://leetcode.com/problems/*
|
||||
// @match https://www.leetcode.com/problems/*
|
||||
// @match https://www.ray.so/*
|
||||
// @match https://ray.so/*
|
||||
// @icon https://www.google.com/s2/favicons?sz=64&domain=leetcode.com
|
||||
// @grant GM_registerMenuCommand
|
||||
// @grant GM_openInTab
|
||||
// @grant GM_log
|
||||
// @grant GM_getTab
|
||||
// @grant GM_setValue
|
||||
// @grant GM_addValueChangeListener
|
||||
// @grant GM_removeValueChangeListener
|
||||
// @grant unsafeWindow
|
||||
// @grant window.close
|
||||
// @grant window.focus
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
let uwindow = unsafeWindow;
|
||||
|
||||
function isLeetcode() {
|
||||
return location.hostname === "leetcode.com";
|
||||
}
|
||||
|
||||
function isRayso() {
|
||||
return location.hostname === "www.ray.so";
|
||||
}
|
||||
|
||||
function waitForRaysoLoad() {
|
||||
return new Promise((resolve) => {
|
||||
let id = GM_addValueChangeListener("leetray.rayso.loaded", () => {
|
||||
resolve();
|
||||
GM_removeValueChangeListener(id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function waitForRaysoExit() {
|
||||
return new Promise((resolve) => {
|
||||
let id = GM_addValueChangeListener("leetray.rayso.exit", () => {
|
||||
resolve();
|
||||
GM_removeValueChangeListener(id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function debug(stuff) {
|
||||
GM_log(`LeetRay DEBUG ${stuff}`);
|
||||
}
|
||||
|
||||
function error(stuff) {
|
||||
GM_log(`LeetRay ERROR ${stuff}`);
|
||||
}
|
||||
|
||||
function leetcodeMain() {
|
||||
const menu_command_id = GM_registerMenuCommand(
|
||||
"Copy screenshot",
|
||||
async function (event) {
|
||||
if (!uwindow.monaco?.editor) {
|
||||
error("monaco.editor not found");
|
||||
return;
|
||||
}
|
||||
|
||||
const monacoEditorEl = document.querySelector(
|
||||
".monaco-editor[data-uri]"
|
||||
);
|
||||
const editorKey = monacoEditorEl.dataset.uri;
|
||||
|
||||
const monacoModel = uwindow.monaco.editor.getModel(editorKey);
|
||||
|
||||
const colors = {
|
||||
rust: "sunset",
|
||||
python: "raindrop",
|
||||
python3: "raindrop",
|
||||
cpp: "midnight",
|
||||
scala: "sunset",
|
||||
javascript: "sunset",
|
||||
typescript: "raindrop",
|
||||
};
|
||||
const sourceCode = monacoModel.getValue();
|
||||
debug("Source code value from editor:");
|
||||
debug(sourceCode);
|
||||
|
||||
const language =
|
||||
monacoModel._languageId === "python3"
|
||||
? "python"
|
||||
: monacoModel._languageId;
|
||||
const title = uwindow.__NEXT_DATA__.query.slug;
|
||||
|
||||
const raysoURL = new URL("https://www.ray.so");
|
||||
|
||||
raysoURL.hash = "__leetray";
|
||||
raysoURL.searchParams.append("code", btoa(sourceCode));
|
||||
raysoURL.searchParams.append("title", title);
|
||||
raysoURL.searchParams.append("padding", 16);
|
||||
language && raysoURL.searchParams.append("language", language);
|
||||
language && raysoURL.searchParams.append("colors", colors[language]);
|
||||
|
||||
debug(`Opening URL: ${raysoURL.toString()}`, {
|
||||
active: true,
|
||||
setParent: true,
|
||||
});
|
||||
const handler = GM_openInTab(raysoURL.toString());
|
||||
|
||||
await waitForRaysoLoad();
|
||||
|
||||
GM_setValue("leetray.screenshot", Date.now());
|
||||
|
||||
await waitForRaysoExit();
|
||||
|
||||
window.focus();
|
||||
|
||||
handler.onclose = () => {
|
||||
alert("Copied screenshot");
|
||||
};
|
||||
},
|
||||
"s"
|
||||
);
|
||||
}
|
||||
|
||||
async function raysoCopyScreenshot() {
|
||||
debug("Copying screenshot");
|
||||
document.querySelector("#app div.setting.export a:nth-child(3)").click();
|
||||
// TODO: flaky mostly
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
function raysoMain() {
|
||||
GM_setValue("leetray.rayso.loaded", Date.now());
|
||||
|
||||
let id = GM_addValueChangeListener("leetray.screenshot", async () => {
|
||||
window.focus();
|
||||
|
||||
await raysoCopyScreenshot();
|
||||
|
||||
GM_removeValueChangeListener(id);
|
||||
GM_setValue("leetray.rayso.exit", Date.now());
|
||||
uwindow.close();
|
||||
});
|
||||
}
|
||||
|
||||
debug("Starting");
|
||||
|
||||
if (isLeetcode()) {
|
||||
leetcodeMain();
|
||||
} else if (isRayso()) {
|
||||
raysoMain();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user