mirror of
https://github.com/Equicord/Equicord.git
synced 2025-01-18 05:13:29 -05:00
Merge remote-tracking branch 'upstream/dev'
This commit is contained in:
commit
68343dc8e2
20 changed files with 669 additions and 86 deletions
|
@ -3,7 +3,8 @@
|
|||
"parser": "@typescript-eslint/parser",
|
||||
"ignorePatterns": [
|
||||
"dist",
|
||||
"browser"
|
||||
"browser",
|
||||
"packages/vencord-types"
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
/// <reference path="../src/modules.d.ts" />
|
||||
/// <reference path="../src/globals.d.ts" />
|
||||
|
||||
import monacoHtmlLocal from "~fileContent/monacoWin.html";
|
||||
import monacoHtmlCdn from "~fileContent/../src/main/monacoWin.html";
|
||||
import monacoHtmlLocal from "file://monacoWin.html?minify";
|
||||
import monacoHtmlCdn from "file://../src/main/monacoWin.html?minify";
|
||||
import * as DataStore from "../src/api/DataStore";
|
||||
import { debounce } from "../src/utils";
|
||||
import { EXTENSION_BASE_URL } from "../src/utils/web-metadata";
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/build.mjs",
|
||||
"buildStandalone": "pnpm build --standalone",
|
||||
"buildWeb": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/buildWeb.mjs",
|
||||
"watch": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/build.mjs --watch",
|
||||
"watch": "pnpm build --watch",
|
||||
"generatePluginJson": "tsx scripts/generatePluginList.ts",
|
||||
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types",
|
||||
"inject": "node scripts/runInstaller.mjs",
|
||||
|
@ -32,7 +33,7 @@
|
|||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --ignore-pattern src/userplugins",
|
||||
"lint-styles": "stylelint \"src/**/*.css\" --ignore-pattern src/userplugins",
|
||||
"lint:fix": "pnpm lint --fix",
|
||||
"test": "pnpm build && pnpm lint:fix && pnpm lint-styles && pnpm testTsc && pnpm generatePluginJson",
|
||||
"test": "pnpm buildStandalone && pnpm lint:fix && pnpm lint-styles && pnpm testTsc && pnpm generatePluginJson",
|
||||
"testWeb": "pnpm lint && pnpm buildWeb && pnpm testTsc",
|
||||
"testTsc": "tsc --noEmit"
|
||||
},
|
||||
|
@ -71,6 +72,7 @@
|
|||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"highlight.js": "10.6.0",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"moment": "^2.29.4",
|
||||
"puppeteer-core": "^19.11.1",
|
||||
"standalone-electron-types": "^1.0.0",
|
||||
|
|
137
pnpm-lock.yaml
137
pnpm-lock.yaml
|
@ -109,6 +109,9 @@ importers:
|
|||
highlight.js:
|
||||
specifier: 10.6.0
|
||||
version: 10.6.0
|
||||
html-minifier-terser:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
moment:
|
||||
specifier: ^2.29.4
|
||||
version: 2.29.4
|
||||
|
@ -547,6 +550,43 @@ packages:
|
|||
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/gen-mapping@0.3.5:
|
||||
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dependencies:
|
||||
'@jridgewell/set-array': 1.2.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
dev: true
|
||||
|
||||
/@jridgewell/resolve-uri@3.1.2:
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/set-array@1.2.1:
|
||||
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/source-map@0.3.6:
|
||||
resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.5
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
dev: true
|
||||
|
||||
/@jridgewell/sourcemap-codec@1.4.15:
|
||||
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/trace-mapping@0.3.25:
|
||||
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
dev: true
|
||||
|
||||
/@nodelib/fs.scandir@2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
|
@ -1060,6 +1100,13 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/camel-case@4.1.2:
|
||||
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
|
||||
dependencies:
|
||||
pascal-case: 3.1.2
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/camelcase-keys@6.2.2:
|
||||
resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -1104,6 +1151,13 @@ packages:
|
|||
mitt: 3.0.0
|
||||
dev: true
|
||||
|
||||
/clean-css@5.3.3:
|
||||
resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==}
|
||||
engines: {node: '>= 10.0'}
|
||||
dependencies:
|
||||
source-map: 0.6.1
|
||||
dev: true
|
||||
|
||||
/cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -1145,6 +1199,15 @@ packages:
|
|||
delayed-stream: 1.0.0
|
||||
dev: false
|
||||
|
||||
/commander@10.0.1:
|
||||
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
|
||||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/commander@2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
dev: true
|
||||
|
||||
/concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
dev: true
|
||||
|
@ -1261,6 +1324,13 @@ packages:
|
|||
esutils: 2.0.3
|
||||
dev: true
|
||||
|
||||
/dot-case@3.0.4:
|
||||
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
dev: true
|
||||
|
@ -1271,6 +1341,11 @@ packages:
|
|||
once: 1.4.0
|
||||
dev: true
|
||||
|
||||
/entities@4.5.0:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
dev: true
|
||||
|
||||
/error-ex@1.3.2:
|
||||
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
|
||||
dependencies:
|
||||
|
@ -1971,6 +2046,20 @@ packages:
|
|||
lru-cache: 6.0.0
|
||||
dev: true
|
||||
|
||||
/html-minifier-terser@7.2.0:
|
||||
resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==}
|
||||
engines: {node: ^14.13.1 || >=16.0.0}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
camel-case: 4.1.2
|
||||
clean-css: 5.3.3
|
||||
commander: 10.0.1
|
||||
entities: 4.5.0
|
||||
param-case: 3.0.4
|
||||
relateurl: 0.2.7
|
||||
terser: 5.31.0
|
||||
dev: true
|
||||
|
||||
/html-tags@3.3.1:
|
||||
resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -2179,6 +2268,12 @@ packages:
|
|||
js-tokens: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lower-case@2.0.2:
|
||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/lru-cache@6.0.0:
|
||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -2310,6 +2405,13 @@ packages:
|
|||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
dev: true
|
||||
|
||||
/no-case@3.0.4:
|
||||
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
||||
dependencies:
|
||||
lower-case: 2.0.2
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/node-fetch@2.6.7:
|
||||
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
|
@ -2401,6 +2503,13 @@ packages:
|
|||
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||
dev: true
|
||||
|
||||
/param-case@3.0.4:
|
||||
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
|
||||
dependencies:
|
||||
dot-case: 3.0.4
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -2418,6 +2527,13 @@ packages:
|
|||
lines-and-columns: 1.2.4
|
||||
dev: true
|
||||
|
||||
/pascal-case@3.1.2:
|
||||
resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -2613,6 +2729,11 @@ packages:
|
|||
strip-indent: 3.0.0
|
||||
dev: true
|
||||
|
||||
/relateurl@0.2.7:
|
||||
resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
|
||||
engines: {node: '>= 0.10'}
|
||||
dev: true
|
||||
|
||||
/require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -2940,6 +3061,17 @@ packages:
|
|||
readable-stream: 3.6.2
|
||||
dev: true
|
||||
|
||||
/terser@5.31.0:
|
||||
resolution: {integrity: sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@jridgewell/source-map': 0.3.6
|
||||
acorn: 8.10.0
|
||||
commander: 2.20.3
|
||||
source-map-support: 0.5.21
|
||||
dev: true
|
||||
|
||||
/text-table@0.2.0:
|
||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||
dev: true
|
||||
|
@ -2983,7 +3115,6 @@ packages:
|
|||
/tslib@2.6.2:
|
||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/tsutils@3.21.0(typescript@5.4.5):
|
||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||
|
@ -3238,7 +3369,3 @@ packages:
|
|||
name: gifenc
|
||||
version: 1.0.3
|
||||
dev: false
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
|
|
@ -20,8 +20,10 @@ import "../suppressExperimentalWarnings.js";
|
|||
import "../checkNodeVersion.js";
|
||||
|
||||
import { exec, execSync } from "child_process";
|
||||
import esbuild from "esbuild";
|
||||
import { constants as FsConstants, readFileSync } from "fs";
|
||||
import { access, readdir, readFile } from "fs/promises";
|
||||
import { minify as minifyHtml } from "html-minifier-terser";
|
||||
import { join, relative } from "path";
|
||||
import { promisify } from "util";
|
||||
|
||||
|
@ -161,21 +163,60 @@ export const gitRemotePlugin = {
|
|||
/**
|
||||
* @type {import("esbuild").Plugin}
|
||||
*/
|
||||
export const fileIncludePlugin = {
|
||||
name: "file-include-plugin",
|
||||
export const fileUrlPlugin = {
|
||||
name: "file-uri-plugin",
|
||||
setup: build => {
|
||||
const filter = /^~fileContent\/.+$/;
|
||||
const filter = /^file:\/\/.+$/;
|
||||
build.onResolve({ filter }, args => ({
|
||||
namespace: "include-file",
|
||||
namespace: "file-uri",
|
||||
path: args.path,
|
||||
pluginData: {
|
||||
path: join(args.resolveDir, args.path.slice("include-file/".length))
|
||||
uri: args.path,
|
||||
path: join(args.resolveDir, args.path.slice("file://".length).split("?")[0])
|
||||
}
|
||||
}));
|
||||
build.onLoad({ filter, namespace: "include-file" }, async ({ pluginData: { path } }) => {
|
||||
const [name, format] = path.split(";");
|
||||
build.onLoad({ filter, namespace: "file-uri" }, async ({ pluginData: { path, uri } }) => {
|
||||
const { searchParams } = new URL(uri);
|
||||
const base64 = searchParams.has("base64");
|
||||
const minify = isStandalone === "true" && searchParams.has("minify");
|
||||
const noTrim = searchParams.get("trim") === "false";
|
||||
|
||||
const encoding = base64 ? "base64" : "utf-8";
|
||||
|
||||
let content;
|
||||
if (!minify) {
|
||||
content = await readFile(path, encoding);
|
||||
if (!noTrim) content = content.trimEnd();
|
||||
} else {
|
||||
if (path.endsWith(".html")) {
|
||||
content = await minifyHtml(await readFile(path, "utf-8"), {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
minifyCSS: true,
|
||||
minifyJS: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true
|
||||
});
|
||||
} else if (/[mc]?[jt]sx?$/.test(path)) {
|
||||
const res = await esbuild.build({
|
||||
entryPoints: [path],
|
||||
write: false,
|
||||
minify: true
|
||||
});
|
||||
content = res.outputFiles[0].text;
|
||||
} else {
|
||||
throw new Error(`Don't know how to minify file type: ${path}`);
|
||||
}
|
||||
|
||||
if (base64)
|
||||
content = Buffer.from(content).toString("base64");
|
||||
}
|
||||
|
||||
return {
|
||||
contents: `export default ${JSON.stringify(await readFile(name, format ?? "utf-8"))}`
|
||||
contents: `export default ${JSON.stringify(content)}`
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -217,7 +258,7 @@ export const commonOpts = {
|
|||
sourcemap: watch ? "inline" : "",
|
||||
legalComments: "linked",
|
||||
banner,
|
||||
plugins: [fileIncludePlugin, gitHashPlugin, gitRemotePlugin, stylePlugin],
|
||||
plugins: [fileUrlPlugin, gitHashPlugin, gitRemotePlugin, stylePlugin],
|
||||
external: ["~plugins", "~git-hash", "~git-remote", "/assets/*"],
|
||||
inject: ["./scripts/build/inject/react.mjs"],
|
||||
jsxFactory: "VencordCreateElement",
|
||||
|
|
|
@ -23,12 +23,11 @@ import "./settings";
|
|||
import { debounce } from "@shared/debounce";
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import { BrowserWindow, ipcMain, shell, systemPreferences } from "electron";
|
||||
import monacoHtml from "file://monacoWin.html?minify&base64";
|
||||
import { FSWatcher, mkdirSync, watch, writeFileSync } from "fs";
|
||||
import { open, readdir, readFile } from "fs/promises";
|
||||
import { join, normalize } from "path";
|
||||
|
||||
import monacoHtml from "~fileContent/monacoWin.html;base64";
|
||||
|
||||
import { ALLOWED_PROTOCOLS, QUICKCSS_PATH, THEMES_DIR } from "./utils/constants";
|
||||
import { makeLinksOpenExternally } from "./utils/externalLinks";
|
||||
|
||||
|
|
2
src/modules.d.ts
vendored
2
src/modules.d.ts
vendored
|
@ -38,7 +38,7 @@ declare module "~git-remote" {
|
|||
export default remote;
|
||||
}
|
||||
|
||||
declare module "~fileContent/*" {
|
||||
declare module "file://*" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
|
|
@ -182,8 +182,8 @@ export default definePlugin({
|
|||
|
||||
// add dearrow button
|
||||
{
|
||||
match: /children:\[(?=null!=\i\?\i\.renderSuppressButton)/,
|
||||
replace: "children:[$self.renderButton(this),",
|
||||
match: /children:\[(?=null!=\i\?(\i)\.renderSuppressButton)/,
|
||||
replace: "children:[$self.renderButton($1),",
|
||||
predicate: () => !settings.store.hideButton
|
||||
}
|
||||
]
|
||||
|
|
35
src/plugins/dontRoundMyTimestamps/index.ts
Normal file
35
src/plugins/dontRoundMyTimestamps/index.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { moment } from "@webpack/common";
|
||||
|
||||
export default definePlugin({
|
||||
name: "DontRoundMyTimestamps",
|
||||
authors: [Devs.Lexi],
|
||||
description: "Always rounds relative timestamps down, so 7.6y becomes 7y instead of 8y",
|
||||
|
||||
start() {
|
||||
moment.relativeTimeRounding(Math.floor);
|
||||
},
|
||||
|
||||
stop() {
|
||||
moment.relativeTimeRounding(Math.round);
|
||||
}
|
||||
});
|
|
@ -67,15 +67,18 @@ export const Magnifier = ErrorBoundary.wrap<MagnifierProps>(({ instance, size: i
|
|||
}
|
||||
};
|
||||
const syncVideos = () => {
|
||||
currentVideoElementRef.current!.currentTime = originalVideoElementRef.current!.currentTime;
|
||||
if (currentVideoElementRef.current && originalVideoElementRef.current)
|
||||
currentVideoElementRef.current.currentTime = originalVideoElementRef.current.currentTime;
|
||||
};
|
||||
|
||||
const updateMousePosition = (e: MouseEvent) => {
|
||||
if (!element.current) return;
|
||||
|
||||
if (instance.state.mouseOver && instance.state.mouseDown) {
|
||||
const offset = size.current / 2;
|
||||
const pos = { x: e.pageX, y: e.pageY };
|
||||
const x = -((pos.x - element.current!.getBoundingClientRect().left) * zoom.current - offset);
|
||||
const y = -((pos.y - element.current!.getBoundingClientRect().top) * zoom.current - offset);
|
||||
const x = -((pos.x - element.current.getBoundingClientRect().left) * zoom.current - offset);
|
||||
const y = -((pos.y - element.current.getBoundingClientRect().top) * zoom.current - offset);
|
||||
setLensPosition({ x: e.x - offset, y: e.y - offset });
|
||||
setImagePosition({ x, y });
|
||||
setOpacity(1);
|
||||
|
@ -184,6 +187,7 @@ export const Magnifier = ErrorBoundary.wrap<MagnifierProps>(({ instance, size: i
|
|||
src={originalVideoElementRef.current?.src ?? instance.props.src}
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
|
|
|
@ -18,88 +18,82 @@
|
|||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import presetQuotesText from "file://quotes.txt";
|
||||
|
||||
// These are Xor encrypted to prevent you from spoiling yourself when you read the source code.
|
||||
// don't worry about it :P
|
||||
const quotes = [
|
||||
"Eyrokac",
|
||||
"Rdcg$l`'k|~n",
|
||||
'H`tf$d&iajo+d`{"',
|
||||
"Sucqplh`(Eclhualva()&",
|
||||
"Lncgmka'8KNMDC,shpanf'`x./,",
|
||||
"Ioqweijnfn*IeuvfvAotkfxo./,",
|
||||
'Hd{#cp\x7Ft$)nbd!{lq%mig~*\x7Fh`v#mk&sm{gx nd#idjb(a\x7Ffao"bja&amdkge!Rloìkhf)hyedfjjb*\'^hzdrdmm$lu\'|ao+mnqw$fijxh~bbmg#Tjmîefd+fnp#lpkffz5',
|
||||
"h",
|
||||
"sijklm&cam*rot\"hjjq'|ak\x7F xmv#wc'ep*mawmvvlrb(|ynr>\"Aqq&cgg-\x7F ugoh%rom)e\x7Fhdpp%$",
|
||||
'Tnfb}"u\'~`nno!kp$vvhfzeyee"a}%Tfam*Xh`fls%Jboldos-"lj`&hn)~ce!`jcbct|)gdbhnf$wikm$zgaxkmc%afely+og"144?\'ign+iu%p$qisiefr gpfa$',
|
||||
"Ndtfv%ahfgk+ghtf$|ir(|z' Oguaw&`ggdj mgw$|ir(me|n",
|
||||
"(!ͣ³$͙ʐ'ͩ¹#",
|
||||
"(ネ◗ロ◑,マ-2ャユ✬",
|
||||
"Ynw#hjil(ze+psgwp|&sgmkr!",
|
||||
"Tikmolh`(fl+a!dvjk\x7F'y|e\x7Fe/,-",
|
||||
"3/3750?5><9>885:7",
|
||||
"mdmt",
|
||||
"Wdn`khc+(oxbeof",
|
||||
'Ig"zkp*\'g{*xolglj`&~g|*gowg/$mgt(Eclm`.#ticf{l*xed"wl`&Kangj igbhqn\'d`dn `v#lqrw{3%$bhv-h|)kangj_imwhlhb',
|
||||
"Tscmw%Tnoa~x",
|
||||
"I‘f#npus(ec`e!vl$lhsm{`ncu\"ekw&f(defeov-$Rnf|)sdu‘pf$wcam{ceg!vl$du'D`d~x-\"jw%oi(okht-\"DJP)Kags,!mq$du'A‐|n sg`akrkq)~jkdl#pj&diefbnf\"jp)&@F\\*{ltq#Hlhrp'",
|
||||
"Ynw$v`&cg`dl fml`%rhlhs*",
|
||||
"Dnl$p%qhz{s' hv$w%hh|aceg!;#gpvt(fl+cndea`&dg|fon&v#wjjqm(",
|
||||
"\ud83d)pft`gs(ec`e!13$qojmz#",
|
||||
"a!njcmr'ide~nu\"lb%rheoedldpz$lu'gbkr",
|
||||
"dn\"zkp&kgo4",
|
||||
"hnpqkw",
|
||||
"sn\"fau",
|
||||
"Sn\"tmqnh}}*musvkaw&flf&+ldv$w%lr{}*aulr#vlao|)cetn\"jp$",
|
||||
"Dxkmc%ot(hhxomwwai'{hln",
|
||||
"hd{#}js&(pe~'sg#gprb(3#\"",
|
||||
"hd{b${",
|
||||
"<;vqkijbq33271:56<3799?24944:",
|
||||
"Thof$lu'ofdn,!qsefc'az*bnrcma+&Om{o+iu\"`khct$)bnrd\"bcdoi&",
|
||||
"snofplkb{)c'r\"lod'|f*aurv#cpno`abchijklmno",
|
||||
"Wdn`khc'|f*eghl{%"
|
||||
];
|
||||
const presetQuotes = presetQuotesText.split("\n").map(quote => /^\s*[^#\s]/.test(quote) && quote.trim()).filter(Boolean) as string[];
|
||||
const noQuotesQuote = "Did you really disable all loading quotes? What a buffoon you are...";
|
||||
|
||||
const settings = definePluginSettings({
|
||||
replaceEvents: {
|
||||
description: "Replace Event Quotes too",
|
||||
description: "Should this plugin also apply during events with special event themed quotes? (e.g. Halloween)",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
enablePluginPresetQuotes: {
|
||||
description: "Enable the quotes preset by this plugin",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true
|
||||
},
|
||||
enableDiscordPresetQuotes: {
|
||||
description: "Enable Discord's preset quotes (including event quotes, during events)",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false
|
||||
},
|
||||
additionalQuotes: {
|
||||
description: "Additional custom quotes to possibly appear, separated by the below delimiter",
|
||||
type: OptionType.STRING,
|
||||
default: "",
|
||||
},
|
||||
additionalQuotesDelimiter: {
|
||||
description: "Delimiter for additional quotes",
|
||||
type: OptionType.STRING,
|
||||
default: "|",
|
||||
},
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "LoadingQuotes",
|
||||
description: "Replace Discords loading quotes",
|
||||
authors: [Devs.Ven, Devs.KraXen72],
|
||||
authors: [Devs.Ven, Devs.KraXen72, Devs.UlyssesZhan],
|
||||
|
||||
settings,
|
||||
|
||||
patches: [
|
||||
{
|
||||
find: ".LOADING_DID_YOU_KNOW}",
|
||||
find: ".LOADING_DID_YOU_KNOW",
|
||||
replacement: [
|
||||
{
|
||||
match: /"_loadingText",function\(\)\{/,
|
||||
replace: "$&return $self.quote;",
|
||||
match: /"_loadingText".+?(?=(\i)\[.{0,10}\.random)/,
|
||||
replace: "$&$self.mutateQuotes($1),"
|
||||
},
|
||||
{
|
||||
match: /"_eventLoadingText",function\(\)\{/,
|
||||
replace: "$&return $self.quote;",
|
||||
match: /"_eventLoadingText".+?(?=(\i)\[.{0,10}\.random)/,
|
||||
replace: "$&$self.mutateQuotes($1),",
|
||||
predicate: () => settings.store.replaceEvents
|
||||
}
|
||||
],
|
||||
]
|
||||
},
|
||||
],
|
||||
|
||||
xor(quote: string) {
|
||||
const key = "read if cute";
|
||||
const codes = Array.from(quote, (s, i) => s.charCodeAt(0) ^ (i % key.length));
|
||||
return String.fromCharCode(...codes);
|
||||
},
|
||||
mutateQuotes(quotes: string[]) {
|
||||
try {
|
||||
const { enableDiscordPresetQuotes, additionalQuotes, additionalQuotesDelimiter, enablePluginPresetQuotes } = settings.store;
|
||||
|
||||
get quote() {
|
||||
return this.xor(quotes[Math.floor(Math.random() * quotes.length)]);
|
||||
if (!enableDiscordPresetQuotes)
|
||||
quotes.length = 0;
|
||||
|
||||
|
||||
if (enablePluginPresetQuotes)
|
||||
quotes.push(...presetQuotes);
|
||||
|
||||
quotes.push(...additionalQuotes.split(additionalQuotesDelimiter).filter(Boolean));
|
||||
|
||||
if (!quotes.length)
|
||||
quotes.push(noQuotesQuote);
|
||||
} catch (e) {
|
||||
new Logger("LoadingQuotes").error("Failed to mutate quotes", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
37
src/plugins/loadingQuotes/quotes.txt
Normal file
37
src/plugins/loadingQuotes/quotes.txt
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Blank lines and lines starting with "#" are ignored
|
||||
|
||||
Explode
|
||||
Read if cute
|
||||
Have a nice day!
|
||||
Starting Lightcord...
|
||||
Loading 0BDFDB.plugin.js...
|
||||
Installing BetterDiscord...
|
||||
h
|
||||
shhhhh did you know that you're my favourite user? But don't tell the others!!
|
||||
Today's video is sponsored by Raid Shadow Legends, one of the biggest mobile role-playing games of 2019 and it's totally free!
|
||||
Never gonna give you up, Never gonna let you down
|
||||
( ͡° ͜ʖ ͡°)
|
||||
(ノ◕ヮ◕)ノ*:・゚✧
|
||||
You look so pretty today!
|
||||
Thinking of a funny quote...
|
||||
3.141592653589793
|
||||
meow
|
||||
Welcome, friend
|
||||
If you, or someone you love, has Ligma, please see the Ligma health line at https://bit.ly/ligma_hotline
|
||||
Trans Rights
|
||||
I’d just like to interject for a moment. What you’re refering to as Linux, is in fact, GNU/Linux, or as I’ve recently taken to calling it, GNU plus Linux.
|
||||
You're doing good today!
|
||||
Don't worry, it's nothing 9 cups of coffee couldn't solve!
|
||||
<EFBFBD>(repeat like 30 times)
|
||||
a light amount of tomfoolery is okay
|
||||
do you love?
|
||||
horror
|
||||
so eepy
|
||||
So without further ado, let's just jump right into it!
|
||||
Dying is absolutely safe
|
||||
hey you! you're cute :))
|
||||
heya ~
|
||||
<:trolley:997086295010594867>
|
||||
Time is gone, space is insane. Here it comes, here again.
|
||||
sometimes it's okay to just guhhhhhhhhhhhhhh
|
||||
Welcome to nginx!
|
36
src/plugins/maskedLinkPaste/index.ts
Normal file
36
src/plugins/maskedLinkPaste/index.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { Devs } from "@utils/constants.js";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
|
||||
const linkRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
|
||||
|
||||
const { SlateTransforms } = findByPropsLazy("SlateTransforms");
|
||||
|
||||
export default definePlugin({
|
||||
name: "MaskedLinkPaste",
|
||||
authors: [Devs.TheSun],
|
||||
description: "Pasting a link while having text selected will paste a hyperlink",
|
||||
patches: [{
|
||||
find: ".selection,preventEmojiSurrogates:",
|
||||
replacement: {
|
||||
match: /(?<=SlateTransforms.delete.{0,50})(\i)\.insertText\((\i)\)/,
|
||||
replace: "$self.handlePaste($1, $2, () => $&)"
|
||||
}
|
||||
}],
|
||||
|
||||
handlePaste(editor, content: string, originalBehavior: () => void) {
|
||||
if (content && linkRegex.test(content) && editor.operations?.[0]?.type === "remove_text") {
|
||||
SlateTransforms.insertText(
|
||||
editor,
|
||||
`[${editor.operations[0].text}](${content})`
|
||||
);
|
||||
}
|
||||
else originalBehavior();
|
||||
}
|
||||
});
|
|
@ -3,6 +3,11 @@
|
|||
color: var(--status-danger, #f04747) !important;
|
||||
}
|
||||
|
||||
/* Markdown title highlighting */
|
||||
.messagelogger-deleted [class*="contents"] :is(h1, h2, h3) {
|
||||
color: var(--status-danger, #f04747) !important;
|
||||
}
|
||||
|
||||
/* Bot "thinking" text highlighting */
|
||||
.messagelogger-deleted [class*="colorStandard"] {
|
||||
color: var(--status-danger, #f04747) !important;
|
||||
|
|
|
@ -87,6 +87,7 @@ export default definePlugin({
|
|||
|
||||
async start() {
|
||||
await DataStore.update("summaries-data", summaries => {
|
||||
summaries ??= {};
|
||||
for (const key of Object.keys(summaries)) {
|
||||
for (let i = summaries[key].length - 1; i >= 0; i--) {
|
||||
if (summaries[key][i].time < Date.now() - 1000 * 60 * 60 * 24 * settings.store.summaryExpiryThresholdDays) {
|
||||
|
|
|
@ -21,8 +21,7 @@ import "./shiki.css";
|
|||
import { enableStyle } from "@api/Styles";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
|
||||
import previewExampleText from "~fileContent/previewExample.tsx";
|
||||
import previewExampleText from "file://previewExample.tsx";
|
||||
|
||||
import { shiki } from "./api/shiki";
|
||||
import { createHighlighter } from "./components/Highlighter";
|
||||
|
|
262
src/plugins/watchTogetherAdblock.desktop/adguard.js
Normal file
262
src/plugins/watchTogetherAdblock.desktop/adguard.js
Normal file
|
@ -0,0 +1,262 @@
|
|||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* This file is part of AdGuard's Block YouTube Ads (https://github.com/AdguardTeam/BlockYouTubeAdsShortcut).
|
||||
*
|
||||
* Copyright (C) AdGuard Team
|
||||
*
|
||||
* AdGuard's Block YouTube Ads is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AdGuard's Block YouTube Ads is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AdGuard's Block YouTube Ads. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const LOGO_ID = "block-youtube-ads-logo";
|
||||
const hiddenCSS = [
|
||||
"#__ffYoutube1",
|
||||
"#__ffYoutube2",
|
||||
"#__ffYoutube3",
|
||||
"#__ffYoutube4",
|
||||
"#feed-pyv-container",
|
||||
"#feedmodule-PRO",
|
||||
"#homepage-chrome-side-promo",
|
||||
"#merch-shelf",
|
||||
"#offer-module",
|
||||
'#pla-shelf > ytd-pla-shelf-renderer[class="style-scope ytd-watch"]',
|
||||
"#pla-shelf",
|
||||
"#premium-yva",
|
||||
"#promo-info",
|
||||
"#promo-list",
|
||||
"#promotion-shelf",
|
||||
"#related > ytd-watch-next-secondary-results-renderer > #items > ytd-compact-promoted-video-renderer.ytd-watch-next-secondary-results-renderer",
|
||||
"#search-pva",
|
||||
"#shelf-pyv-container",
|
||||
"#video-masthead",
|
||||
"#watch-branded-actions",
|
||||
"#watch-buy-urls",
|
||||
"#watch-channel-brand-div",
|
||||
"#watch7-branded-banner",
|
||||
"#YtKevlarVisibilityIdentifier",
|
||||
"#YtSparklesVisibilityIdentifier",
|
||||
".carousel-offer-url-container",
|
||||
".companion-ad-container",
|
||||
".GoogleActiveViewElement",
|
||||
'.list-view[style="margin: 7px 0pt;"]',
|
||||
".promoted-sparkles-text-search-root-container",
|
||||
".promoted-videos",
|
||||
".searchView.list-view",
|
||||
".sparkles-light-cta",
|
||||
".watch-extra-info-column",
|
||||
".watch-extra-info-right",
|
||||
".ytd-carousel-ad-renderer",
|
||||
".ytd-compact-promoted-video-renderer",
|
||||
".ytd-companion-slot-renderer",
|
||||
".ytd-merch-shelf-renderer",
|
||||
".ytd-player-legacy-desktop-watch-ads-renderer",
|
||||
".ytd-promoted-sparkles-text-search-renderer",
|
||||
".ytd-promoted-video-renderer",
|
||||
".ytd-search-pyv-renderer",
|
||||
".ytd-video-masthead-ad-v3-renderer",
|
||||
".ytp-ad-action-interstitial-background-container",
|
||||
".ytp-ad-action-interstitial-slot",
|
||||
".ytp-ad-image-overlay",
|
||||
".ytp-ad-overlay-container",
|
||||
".ytp-ad-progress",
|
||||
".ytp-ad-progress-list",
|
||||
'[class*="ytd-display-ad-"]',
|
||||
'[layout*="display-ad-"]',
|
||||
'a[href^="http://www.youtube.com/cthru?"]',
|
||||
'a[href^="https://www.youtube.com/cthru?"]',
|
||||
"ytd-action-companion-ad-renderer",
|
||||
"ytd-banner-promo-renderer",
|
||||
"ytd-compact-promoted-video-renderer",
|
||||
"ytd-companion-slot-renderer",
|
||||
"ytd-display-ad-renderer",
|
||||
"ytd-promoted-sparkles-text-search-renderer",
|
||||
"ytd-promoted-sparkles-web-renderer",
|
||||
"ytd-search-pyv-renderer",
|
||||
"ytd-single-option-survey-renderer",
|
||||
"ytd-video-masthead-ad-advertiser-info-renderer",
|
||||
"ytd-video-masthead-ad-v3-renderer",
|
||||
"YTM-PROMOTED-VIDEO-RENDERER",
|
||||
];
|
||||
/**
|
||||
* Adds CSS to the page
|
||||
*/
|
||||
const hideElements = () => {
|
||||
const selectors = hiddenCSS;
|
||||
if (!selectors) {
|
||||
return;
|
||||
}
|
||||
const rule = selectors.join(", ") + " { display: none!important; }";
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = rule;
|
||||
document.head.appendChild(style);
|
||||
};
|
||||
/**
|
||||
* Calls the "callback" function on every DOM change, but not for the tracked events
|
||||
* @param {Function} callback callback function
|
||||
*/
|
||||
const observeDomChanges = callback => {
|
||||
const domMutationObserver = new MutationObserver(mutations => {
|
||||
callback(mutations);
|
||||
});
|
||||
domMutationObserver.observe(document.documentElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* This function is supposed to be called on every DOM change
|
||||
*/
|
||||
const hideDynamicAds = () => {
|
||||
const elements = document.querySelectorAll("#contents > ytd-rich-item-renderer ytd-display-ad-renderer");
|
||||
if (elements.length === 0) {
|
||||
return;
|
||||
}
|
||||
elements.forEach(el => {
|
||||
if (el.parentNode && el.parentNode.parentNode) {
|
||||
const parent = el.parentNode.parentNode;
|
||||
if (parent.localName === "ytd-rich-item-renderer") {
|
||||
parent.style.display = "none";
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* This function checks if the video ads are currently running
|
||||
* and auto-clicks the skip button.
|
||||
*/
|
||||
const autoSkipAds = () => {
|
||||
// If there's a video that plays the ad at this moment, scroll this ad
|
||||
if (document.querySelector(".ad-showing")) {
|
||||
const video = document.querySelector("video");
|
||||
if (video && video.duration) {
|
||||
video.currentTime = video.duration;
|
||||
// Skip button should appear after that,
|
||||
// now simply click it automatically
|
||||
setTimeout(() => {
|
||||
const skipBtn = document.querySelector("button.ytp-ad-skip-button");
|
||||
if (skipBtn) {
|
||||
skipBtn.click();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* This function overrides a property on the specified object.
|
||||
*
|
||||
* @param {object} obj object to look for properties in
|
||||
* @param {string} propertyName property to override
|
||||
* @param {*} overrideValue value to set
|
||||
*/
|
||||
const overrideObject = (obj, propertyName, overrideValue) => {
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
let overriden = false;
|
||||
for (const key in obj) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (obj.hasOwnProperty(key) && key === propertyName) {
|
||||
obj[key] = overrideValue;
|
||||
overriden = true;
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
} else if (obj.hasOwnProperty(key) && typeof obj[key] === "object") {
|
||||
if (overrideObject(obj[key], propertyName, overrideValue)) {
|
||||
overriden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return overriden;
|
||||
};
|
||||
/**
|
||||
* Overrides JSON.parse and Response.json functions.
|
||||
* Examines these functions arguments, looks for properties with the specified name there
|
||||
* and if it exists, changes it's value to what was specified.
|
||||
*
|
||||
* @param {string} propertyName name of the property
|
||||
* @param {*} overrideValue new value for the property
|
||||
*/
|
||||
const jsonOverride = (propertyName, overrideValue) => {
|
||||
const nativeJSONParse = JSON.parse;
|
||||
JSON.parse = (...args) => {
|
||||
const obj = nativeJSONParse.apply(this, args);
|
||||
// Override it's props and return back to the caller
|
||||
overrideObject(obj, propertyName, overrideValue);
|
||||
return obj;
|
||||
};
|
||||
// Override Response.prototype.json
|
||||
const nativeResponseJson = Response.prototype.json;
|
||||
Response.prototype.json = new Proxy(nativeResponseJson, {
|
||||
apply(...args) {
|
||||
// Call the target function, get the original Promise
|
||||
const promise = Reflect.apply(...args);
|
||||
// Create a new one and override the JSON inside
|
||||
return new Promise((resolve, reject) => {
|
||||
promise.then(data => {
|
||||
overrideObject(data, propertyName, overrideValue);
|
||||
resolve(data);
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
const addAdGuardLogoStyle = () => { };
|
||||
const addAdGuardLogo = () => {
|
||||
if (document.getElementById(LOGO_ID)) {
|
||||
return;
|
||||
}
|
||||
const logo = document.createElement("span");
|
||||
logo.innerHTML = "__logo_text__";
|
||||
logo.setAttribute("id", LOGO_ID);
|
||||
if (window.location.hostname === "m.youtube.com") {
|
||||
const btn = document.querySelector("header.mobile-topbar-header > button");
|
||||
if (btn) {
|
||||
btn.parentNode?.insertBefore(logo, btn.nextSibling);
|
||||
addAdGuardLogoStyle();
|
||||
}
|
||||
} else if (window.location.hostname === "www.youtube.com") {
|
||||
const code = document.getElementById("country-code");
|
||||
if (code) {
|
||||
code.innerHTML = "";
|
||||
code.appendChild(logo);
|
||||
addAdGuardLogoStyle();
|
||||
}
|
||||
} else if (window.location.hostname === "music.youtube.com") {
|
||||
const el = document.querySelector(".ytmusic-nav-bar#left-content");
|
||||
if (el) {
|
||||
el.appendChild(logo);
|
||||
addAdGuardLogoStyle();
|
||||
}
|
||||
} else if (window.location.hostname === "www.youtube-nocookie.com") {
|
||||
const code = document.querySelector("#yt-masthead #logo-container .content-region");
|
||||
if (code) {
|
||||
code.innerHTML = "";
|
||||
code.appendChild(logo);
|
||||
addAdGuardLogoStyle();
|
||||
}
|
||||
}
|
||||
};
|
||||
// Removes ads metadata from YouTube XHR requests
|
||||
jsonOverride("adPlacements", []);
|
||||
jsonOverride("playerAds", []);
|
||||
// Applies CSS that hides YouTube ad elements
|
||||
hideElements();
|
||||
// Some changes should be re-evaluated on every page change
|
||||
addAdGuardLogo();
|
||||
hideDynamicAds();
|
||||
autoSkipAds();
|
||||
observeDomChanges(() => {
|
||||
addAdGuardLogo();
|
||||
hideDynamicAds();
|
||||
autoSkipAds();
|
||||
});
|
15
src/plugins/watchTogetherAdblock.desktop/index.ts
Normal file
15
src/plugins/watchTogetherAdblock.desktop/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
|
||||
// The entire code of this plugin can be found in native.ts
|
||||
export default definePlugin({
|
||||
name: "WatchTogetherAdblock",
|
||||
description: "Block ads in the YouTube WatchTogether activity via AdGuard",
|
||||
authors: [Devs.ImLvna],
|
||||
});
|
21
src/plugins/watchTogetherAdblock.desktop/native.ts
Normal file
21
src/plugins/watchTogetherAdblock.desktop/native.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { RendererSettings } from "@main/settings";
|
||||
import { app } from "electron";
|
||||
import adguard from "file://adguard.js?minify";
|
||||
|
||||
app.on("browser-window-created", (_, win) => {
|
||||
win.webContents.on("frame-created", (_, { frame }) => {
|
||||
frame.once("dom-ready", () => {
|
||||
if (frame.url.includes("discordsays") && frame.url.includes("youtube.com")) {
|
||||
if (!RendererSettings.store.plugins?.WatchTogetherAdblock?.enabled) return;
|
||||
|
||||
frame.executeJavaScript(adguard);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -188,7 +188,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
|||
id: 296776625432035328n,
|
||||
},
|
||||
TheSun: {
|
||||
name: "ActuallyTheSun",
|
||||
name: "sunnie",
|
||||
id: 406028027768733696n
|
||||
},
|
||||
axyie: {
|
||||
|
@ -404,6 +404,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
|||
name: "maisy",
|
||||
id: 257109471589957632n,
|
||||
},
|
||||
Lexi: {
|
||||
name: "Lexi",
|
||||
id: 506101469787717658n
|
||||
},
|
||||
Mopi: {
|
||||
name: "Mopi",
|
||||
id: 1022189106614243350n
|
||||
|
|
Loading…
Reference in a new issue