diff --git a/.npmrc b/.npmrc
index 319e41e6..336b6ad1 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1 +1,2 @@
strict-peer-dependencies=false
+package-manager-strict=false
diff --git a/package.json b/package.json
index c2a7c6a1..f25898b0 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "vencord",
"private": "true",
- "version": "1.8.4",
+ "version": "1.8.5",
"description": "The other cutest Discord client mod",
"homepage": "https://github.com/Equicord/Equicord#readme",
"bugs": {
@@ -24,16 +24,17 @@
"scripts": {
"build": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/build.mjs",
"buildWeb": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/buildWeb.mjs",
+ "watch": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/build.mjs --watch",
"generatePluginJson": "tsx scripts/generatePluginList.ts",
+ "generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types",
"inject": "node scripts/runInstaller.mjs",
+ "uninject": "node scripts/runInstaller.mjs",
"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",
"testWeb": "pnpm lint && pnpm buildWeb && pnpm testTsc",
- "testTsc": "tsc --noEmit",
- "uninject": "node scripts/runInstaller.mjs",
- "watch": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/build.mjs --watch"
+ "testTsc": "tsc --noEmit"
},
"dependencies": {
"@sapphi-red/web-noise-suppressor": "0.3.3",
@@ -75,10 +76,12 @@
"standalone-electron-types": "^1.0.0",
"stylelint": "^15.6.0",
"stylelint-config-standard": "^33.0.0",
+ "ts-patch": "^3.1.2",
"tsx": "^3.12.7",
"type-fest": "^3.9.0",
"typed-emitter": "^2.1.0",
- "typescript": "^5.0.4",
+ "typescript": "^5.4.5",
+ "typescript-transform-paths": "^3.4.7",
"zip-local": "^0.3.5",
"zustand": "^3.7.2"
},
diff --git a/packages/vencord-types/.gitignore b/packages/vencord-types/.gitignore
new file mode 100644
index 00000000..bc23f8b6
--- /dev/null
+++ b/packages/vencord-types/.gitignore
@@ -0,0 +1,7 @@
+*
+!.*ignore
+!package.json
+!*.md
+!prepare.ts
+!index.d.ts
+!globals.d.ts
diff --git a/packages/vencord-types/.npmignore b/packages/vencord-types/.npmignore
new file mode 100644
index 00000000..28822788
--- /dev/null
+++ b/packages/vencord-types/.npmignore
@@ -0,0 +1,4 @@
+node_modules
+prepare.ts
+.gitignore
+HOW2PUB.md
diff --git a/packages/vencord-types/HOW2PUB.md b/packages/vencord-types/HOW2PUB.md
new file mode 100644
index 00000000..2085898e
--- /dev/null
+++ b/packages/vencord-types/HOW2PUB.md
@@ -0,0 +1,5 @@
+# How to publish
+
+1. run `pnpm generateTypes` in the project root
+2. bump package.json version
+3. npm publish
diff --git a/packages/vencord-types/README.md b/packages/vencord-types/README.md
new file mode 100644
index 00000000..0513f870
--- /dev/null
+++ b/packages/vencord-types/README.md
@@ -0,0 +1,11 @@
+# Vencord Types
+
+Typings for Vencord's api, published to npm
+
+```sh
+npm i @vencord/types
+
+yarn add @vencord/types
+
+pnpm add @vencord/types
+```
diff --git a/packages/vencord-types/globals.d.ts b/packages/vencord-types/globals.d.ts
new file mode 100644
index 00000000..a5916e54
--- /dev/null
+++ b/packages/vencord-types/globals.d.ts
@@ -0,0 +1,24 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 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 .
+*/
+
+declare global {
+ export var VencordNative: typeof import("./VencordNative").default;
+ export var Vencord: typeof import("./Vencord");
+}
+
+export { };
diff --git a/packages/vencord-types/index.d.ts b/packages/vencord-types/index.d.ts
new file mode 100644
index 00000000..c7d8253c
--- /dev/null
+++ b/packages/vencord-types/index.d.ts
@@ -0,0 +1,5 @@
+/* eslint-disable */
+
+///
+///
+///
diff --git a/packages/vencord-types/package.json b/packages/vencord-types/package.json
new file mode 100644
index 00000000..8f9d852e
--- /dev/null
+++ b/packages/vencord-types/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@vencord/types",
+ "private": false,
+ "version": "0.1.3",
+ "description": "",
+ "types": "index.d.ts",
+ "scripts": {
+ "prepublishOnly": "tsx ./prepare.ts",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "Vencord",
+ "license": "GPL-3.0",
+ "devDependencies": {
+ "@types/fs-extra": "^11.0.4",
+ "fs-extra": "^11.2.0",
+ "tsx": "^3.12.6"
+ },
+ "dependencies": {
+ "@types/lodash": "^4.14.191",
+ "@types/node": "^18.11.18",
+ "@types/react": "^18.2.0",
+ "@types/react-dom": "^18.0.10",
+ "discord-types": "^1.3.26",
+ "standalone-electron-types": "^1.0.0",
+ "type-fest": "^3.5.3"
+ }
+}
diff --git a/packages/vencord-types/prepare.ts b/packages/vencord-types/prepare.ts
new file mode 100644
index 00000000..de1f6b04
--- /dev/null
+++ b/packages/vencord-types/prepare.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 .
+*/
+
+import { cpSync, moveSync, readdirSync, rmSync } from "fs-extra";
+import { join } from "path";
+
+readdirSync(join(__dirname, "src"))
+ .forEach(child => moveSync(join(__dirname, "src", child), join(__dirname, child), { overwrite: true }));
+
+const VencordSrc = join(__dirname, "..", "..", "src");
+
+for (const file of ["preload.d.ts", "userplugins", "main", "debug", "src", "browser", "scripts"]) {
+ rmSync(join(__dirname, file), { recursive: true, force: true });
+}
+
+function copyDtsFiles(from: string, to: string) {
+ for (const file of readdirSync(from, { withFileTypes: true })) {
+ // bad
+ if (from === VencordSrc && file.name === "globals.d.ts") continue;
+
+ const fullFrom = join(from, file.name);
+ const fullTo = join(to, file.name);
+
+ if (file.isDirectory()) {
+ copyDtsFiles(fullFrom, fullTo);
+ } else if (file.name.endsWith(".d.ts")) {
+ cpSync(fullFrom, fullTo);
+ }
+ }
+}
+
+copyDtsFiles(VencordSrc, __dirname);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 935a6449..fcd0da45 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,138 +8,180 @@ patchedDependencies:
hash: xm46kqcmdgzlmm4aifkfpxaho4
path: patches/eslint@8.46.0.patch
-dependencies:
- '@sapphi-red/web-noise-suppressor':
- specifier: 0.3.3
- version: 0.3.3
- '@types/less':
- specifier: ^3.0.6
- version: 3.0.6(patch_hash=krcufrsfhsuxuoj7hocqugs6zi)
- '@types/stylus':
- specifier: ^0.48.42
- version: 0.48.42
- '@types/tinycolor2':
- specifier: ^1.4.6
- version: 1.4.6
- '@vap/core':
- specifier: 0.0.12
- version: 0.0.12
- '@vap/shiki':
- specifier: 0.10.5
- version: 0.10.5
- axios:
- specifier: ^1.6.8
- version: 1.6.8
- fflate:
- specifier: ^0.7.4
- version: 0.7.4
- gifenc:
- specifier: github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3
- version: github.com/mattdesl/gifenc/64842fca317b112a8590f8fef2bf3825da8f6fe3
- monaco-editor:
- specifier: ^0.43.0
- version: 0.43.0
- nanoid:
- specifier: ^4.0.2
- version: 4.0.2
- usercss-meta:
- specifier: ^0.12.0
- version: 0.12.0
- virtual-merge:
- specifier: ^1.0.1
- version: 1.0.1
+importers:
-devDependencies:
- '@react-spring/web':
- specifier: ^9.7.3
- version: 9.7.3(react-dom@18.2.0)(react@18.2.0)
- '@types/chrome':
- specifier: ^0.0.246
- version: 0.0.246
- '@types/diff':
- specifier: ^5.0.3
- version: 5.0.3
- '@types/lodash':
- specifier: ^4.14.194
- version: 4.14.194
- '@types/node':
- specifier: ^18.16.3
- version: 18.16.3
- '@types/react':
- specifier: ^18.2.0
- version: 18.2.0
- '@types/react-dom':
- specifier: ^18.2.1
- version: 18.2.1
- '@types/yazl':
- specifier: ^2.4.2
- version: 2.4.2
- '@typescript-eslint/eslint-plugin':
- specifier: ^5.59.1
- version: 5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.46.0)(typescript@5.0.4)
- '@typescript-eslint/parser':
- specifier: ^5.59.1
- version: 5.59.1(eslint@8.46.0)(typescript@5.0.4)
- diff:
- specifier: ^5.1.0
- version: 5.1.0
- discord-types:
- specifier: ^1.3.26
- version: 1.3.26
- esbuild:
- specifier: ^0.15.18
- version: 0.15.18
- eslint:
- specifier: ^8.46.0
- version: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
- eslint-import-resolver-alias:
- specifier: ^1.1.2
- version: 1.1.2
- eslint-plugin-simple-header:
- specifier: ^1.0.2
- version: 1.0.2
- eslint-plugin-simple-import-sort:
- specifier: ^10.0.0
- version: 10.0.0(eslint@8.46.0)
- eslint-plugin-unused-imports:
- specifier: ^2.0.0
- version: 2.0.0(@typescript-eslint/eslint-plugin@5.59.1)(eslint@8.46.0)
- highlight.js:
- specifier: 10.6.0
- version: 10.6.0
- moment:
- specifier: ^2.29.4
- version: 2.29.4
- puppeteer-core:
- specifier: ^19.11.1
- version: 19.11.1(typescript@5.0.4)
- standalone-electron-types:
- specifier: ^1.0.0
- version: 1.0.0
- stylelint:
- specifier: ^15.6.0
- version: 15.6.0
- stylelint-config-standard:
- specifier: ^33.0.0
- version: 33.0.0(stylelint@15.6.0)
- tsx:
- specifier: ^3.12.7
- version: 3.12.7
- type-fest:
- specifier: ^3.9.0
- version: 3.9.0
- typed-emitter:
- specifier: ^2.1.0
- version: 2.1.0
- typescript:
- specifier: ^5.0.4
- version: 5.0.4
- zip-local:
- specifier: ^0.3.5
- version: 0.3.5
- zustand:
- specifier: ^3.7.2
- version: 3.7.2(react@18.2.0)
+ .:
+ dependencies:
+ '@sapphi-red/web-noise-suppressor':
+ specifier: 0.3.3
+ version: 0.3.3
+ '@types/less':
+ specifier: ^3.0.6
+ version: 3.0.6(patch_hash=krcufrsfhsuxuoj7hocqugs6zi)
+ '@types/stylus':
+ specifier: ^0.48.42
+ version: 0.48.42
+ '@types/tinycolor2':
+ specifier: ^1.4.6
+ version: 1.4.6
+ '@vap/core':
+ specifier: 0.0.12
+ version: 0.0.12
+ '@vap/shiki':
+ specifier: 0.10.5
+ version: 0.10.5
+ axios:
+ specifier: ^1.6.8
+ version: 1.6.8
+ fflate:
+ specifier: ^0.7.4
+ version: 0.7.4
+ gifenc:
+ specifier: github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3
+ version: github.com/mattdesl/gifenc/64842fca317b112a8590f8fef2bf3825da8f6fe3
+ monaco-editor:
+ specifier: ^0.43.0
+ version: 0.43.0
+ nanoid:
+ specifier: ^4.0.2
+ version: 4.0.2
+ usercss-meta:
+ specifier: ^0.12.0
+ version: 0.12.0
+ virtual-merge:
+ specifier: ^1.0.1
+ version: 1.0.1
+ devDependencies:
+ '@react-spring/web':
+ specifier: ^9.7.3
+ version: 9.7.3(react-dom@18.2.0)(react@18.2.0)
+ '@types/chrome':
+ specifier: ^0.0.246
+ version: 0.0.246
+ '@types/diff':
+ specifier: ^5.0.3
+ version: 5.0.3
+ '@types/lodash':
+ specifier: ^4.14.194
+ version: 4.14.194
+ '@types/node':
+ specifier: ^18.16.3
+ version: 18.16.3
+ '@types/react':
+ specifier: ^18.2.0
+ version: 18.2.0
+ '@types/react-dom':
+ specifier: ^18.2.1
+ version: 18.2.1
+ '@types/yazl':
+ specifier: ^2.4.2
+ version: 2.4.2
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^5.59.1
+ version: 5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.46.0)(typescript@5.4.5)
+ '@typescript-eslint/parser':
+ specifier: ^5.59.1
+ version: 5.59.1(eslint@8.46.0)(typescript@5.4.5)
+ diff:
+ specifier: ^5.1.0
+ version: 5.1.0
+ discord-types:
+ specifier: ^1.3.26
+ version: 1.3.26
+ esbuild:
+ specifier: ^0.15.18
+ version: 0.15.18
+ eslint:
+ specifier: ^8.46.0
+ version: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
+ eslint-import-resolver-alias:
+ specifier: ^1.1.2
+ version: 1.1.2
+ eslint-plugin-simple-header:
+ specifier: ^1.0.2
+ version: 1.0.2
+ eslint-plugin-simple-import-sort:
+ specifier: ^10.0.0
+ version: 10.0.0(eslint@8.46.0)
+ eslint-plugin-unused-imports:
+ specifier: ^2.0.0
+ version: 2.0.0(@typescript-eslint/eslint-plugin@5.59.1)(eslint@8.46.0)
+ highlight.js:
+ specifier: 10.6.0
+ version: 10.6.0
+ moment:
+ specifier: ^2.29.4
+ version: 2.29.4
+ puppeteer-core:
+ specifier: ^19.11.1
+ version: 19.11.1(typescript@5.4.5)
+ standalone-electron-types:
+ specifier: ^1.0.0
+ version: 1.0.0
+ stylelint:
+ specifier: ^15.6.0
+ version: 15.6.0
+ stylelint-config-standard:
+ specifier: ^33.0.0
+ version: 33.0.0(stylelint@15.6.0)
+ ts-patch:
+ specifier: ^3.1.2
+ version: 3.1.2
+ tsx:
+ specifier: ^3.12.7
+ version: 3.12.7
+ type-fest:
+ specifier: ^3.9.0
+ version: 3.9.0
+ typed-emitter:
+ specifier: ^2.1.0
+ version: 2.1.0
+ typescript:
+ specifier: ^5.4.5
+ version: 5.4.5
+ typescript-transform-paths:
+ specifier: ^3.4.7
+ version: 3.4.7(typescript@5.4.5)
+ zip-local:
+ specifier: ^0.3.5
+ version: 0.3.5
+ zustand:
+ specifier: ^3.7.2
+ version: 3.7.2(react@18.2.0)
+
+ packages/vencord-types:
+ dependencies:
+ '@types/lodash':
+ specifier: ^4.14.191
+ version: 4.14.194
+ '@types/node':
+ specifier: ^18.11.18
+ version: 18.16.3
+ '@types/react':
+ specifier: ^18.2.0
+ version: 18.2.0
+ '@types/react-dom':
+ specifier: ^18.0.10
+ version: 18.2.1
+ discord-types:
+ specifier: ^1.3.26
+ version: 1.3.26
+ standalone-electron-types:
+ specifier: ^1.0.0
+ version: 1.0.0
+ type-fest:
+ specifier: ^3.5.3
+ version: 3.9.0
+ devDependencies:
+ '@types/fs-extra':
+ specifier: ^11.0.4
+ version: 11.0.4
+ fs-extra:
+ specifier: ^11.2.0
+ version: 11.2.0
+ tsx:
+ specifier: ^3.12.6
+ version: 3.12.7
packages:
@@ -526,7 +568,7 @@ packages:
fastq: 1.13.0
dev: true
- /@puppeteer/browsers@0.5.0(typescript@5.0.4):
+ /@puppeteer/browsers@0.5.0(typescript@5.4.5):
resolution: {integrity: sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ==}
engines: {node: '>=14.1.0'}
hasBin: true
@@ -542,7 +584,7 @@ packages:
progress: 2.0.3
proxy-from-env: 1.1.0
tar-fs: 2.1.1
- typescript: 5.0.4
+ typescript: 5.4.5
unbzip2-stream: 1.4.3
yargs: 17.7.1
transitivePeerDependencies:
@@ -622,6 +664,13 @@ packages:
resolution: {integrity: sha512-lB98tui0uxc7erbj0serZfJlHKLNJHwBltPnbmO1WRpL5T325GOHRiQfr2E29V2q+S1brDO63Fpdt6vb3bES9Q==}
dev: true
+ /@types/fs-extra@11.0.4:
+ resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==}
+ dependencies:
+ '@types/jsonfile': 6.1.4
+ '@types/node': 18.16.3
+ dev: true
+
/@types/har-format@1.2.13:
resolution: {integrity: sha512-PwBsCBD3lDODn4xpje3Y1di0aDJp4Ww7aSfMRVw6ysnxD4I7Wmq2mBkSKaDtN403hqH5sp6c9xQUvFYY3+lkBg==}
dev: true
@@ -630,6 +679,12 @@ packages:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
+ /@types/jsonfile@6.1.4:
+ resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==}
+ dependencies:
+ '@types/node': 18.16.3
+ dev: true
+
/@types/less@3.0.6(patch_hash=krcufrsfhsuxuoj7hocqugs6zi):
resolution: {integrity: sha512-PecSzorDGdabF57OBeQO/xFbAkYWo88g4Xvnsx7LRwqLC17I7OoKtA3bQB9uXkY6UkMWCOsA8HSVpaoitscdXw==}
dev: false
@@ -637,7 +692,6 @@ packages:
/@types/lodash@4.14.194:
resolution: {integrity: sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==}
- dev: true
/@types/minimist@1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
@@ -652,20 +706,17 @@ packages:
/@types/prop-types@15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
- dev: true
/@types/react-dom@18.2.1:
resolution: {integrity: sha512-8QZEV9+Kwy7tXFmjJrp3XUKQSs9LTnE0KnoUb0YCguWBiNW0Yfb2iBMYZ08WPg35IR6P3Z0s00B15SwZnO26+w==}
dependencies:
'@types/react': 18.2.0
- dev: true
/@types/react@17.0.2:
resolution: {integrity: sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA==}
dependencies:
'@types/prop-types': 15.7.5
csstype: 3.1.2
- dev: true
/@types/react@18.2.0:
resolution: {integrity: sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==}
@@ -673,11 +724,9 @@ packages:
'@types/prop-types': 15.7.5
'@types/scheduler': 0.16.3
csstype: 3.1.2
- dev: true
/@types/scheduler@0.16.3:
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
- dev: true
/@types/semver@7.3.13:
resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
@@ -707,7 +756,7 @@ packages:
'@types/node': 18.16.3
dev: true
- /@typescript-eslint/eslint-plugin@5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.46.0)(typescript@5.0.4):
+ /@typescript-eslint/eslint-plugin@5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.46.0)(typescript@5.4.5):
resolution: {integrity: sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -721,23 +770,23 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.5.1
- '@typescript-eslint/parser': 5.59.1(eslint@8.46.0)(typescript@5.0.4)
+ '@typescript-eslint/parser': 5.59.1(eslint@8.46.0)(typescript@5.4.5)
'@typescript-eslint/scope-manager': 5.59.1
- '@typescript-eslint/type-utils': 5.59.1(eslint@8.46.0)(typescript@5.0.4)
- '@typescript-eslint/utils': 5.59.1(eslint@8.46.0)(typescript@5.0.4)
+ '@typescript-eslint/type-utils': 5.59.1(eslint@8.46.0)(typescript@5.4.5)
+ '@typescript-eslint/utils': 5.59.1(eslint@8.46.0)(typescript@5.4.5)
debug: 4.3.4
eslint: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
grapheme-splitter: 1.0.4
ignore: 5.2.4
natural-compare-lite: 1.4.0
semver: 7.5.0
- tsutils: 3.21.0(typescript@5.0.4)
- typescript: 5.0.4
+ tsutils: 3.21.0(typescript@5.4.5)
+ typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/parser@5.59.1(eslint@8.46.0)(typescript@5.0.4):
+ /@typescript-eslint/parser@5.59.1(eslint@8.46.0)(typescript@5.4.5):
resolution: {integrity: sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -751,10 +800,10 @@ packages:
dependencies:
'@typescript-eslint/scope-manager': 5.59.1
'@typescript-eslint/types': 5.59.1
- '@typescript-eslint/typescript-estree': 5.59.1(typescript@5.0.4)
+ '@typescript-eslint/typescript-estree': 5.59.1(typescript@5.4.5)
debug: 4.3.4
eslint: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
- typescript: 5.0.4
+ typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
@@ -767,7 +816,7 @@ packages:
'@typescript-eslint/visitor-keys': 5.59.1
dev: true
- /@typescript-eslint/type-utils@5.59.1(eslint@8.46.0)(typescript@5.0.4):
+ /@typescript-eslint/type-utils@5.59.1(eslint@8.46.0)(typescript@5.4.5):
resolution: {integrity: sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -779,12 +828,12 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 5.59.1(typescript@5.0.4)
- '@typescript-eslint/utils': 5.59.1(eslint@8.46.0)(typescript@5.0.4)
+ '@typescript-eslint/typescript-estree': 5.59.1(typescript@5.4.5)
+ '@typescript-eslint/utils': 5.59.1(eslint@8.46.0)(typescript@5.4.5)
debug: 4.3.4
eslint: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
- tsutils: 3.21.0(typescript@5.0.4)
- typescript: 5.0.4
+ tsutils: 3.21.0(typescript@5.4.5)
+ typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
@@ -794,7 +843,7 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /@typescript-eslint/typescript-estree@5.59.1(typescript@5.0.4):
+ /@typescript-eslint/typescript-estree@5.59.1(typescript@5.4.5):
resolution: {integrity: sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -808,14 +857,14 @@ packages:
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
- semver: 7.5.0
- tsutils: 3.21.0(typescript@5.0.4)
- typescript: 5.0.4
+ semver: 7.6.2
+ tsutils: 3.21.0(typescript@5.4.5)
+ typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/utils@5.59.1(eslint@8.46.0)(typescript@5.0.4):
+ /@typescript-eslint/utils@5.59.1(eslint@8.46.0)(typescript@5.4.5):
resolution: {integrity: sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -829,7 +878,7 @@ packages:
'@types/semver': 7.3.13
'@typescript-eslint/scope-manager': 5.59.1
'@typescript-eslint/types': 5.59.1
- '@typescript-eslint/typescript-estree': 5.59.1(typescript@5.0.4)
+ '@typescript-eslint/typescript-estree': 5.59.1(typescript@5.4.5)
eslint: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
eslint-scope: 5.1.1
semver: 7.5.0
@@ -1148,7 +1197,6 @@ packages:
/csstype@3.1.2:
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
- dev: true
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
@@ -1205,7 +1253,6 @@ packages:
dependencies:
'@types/react': 17.0.2
moment: 2.29.4
- dev: true
/doctrine@3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
@@ -1522,7 +1569,7 @@ packages:
eslint:
optional: true
dependencies:
- '@typescript-eslint/eslint-plugin': 5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.46.0)(typescript@5.0.4)
+ '@typescript-eslint/eslint-plugin': 5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.46.0)(typescript@5.4.5)
eslint: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4)
eslint-rule-composer: 0.3.0
dev: true
@@ -1770,6 +1817,15 @@ packages:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
dev: true
+ /fs-extra@11.2.0:
+ resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
+ engines: {node: '>=14.14'}
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 6.1.0
+ universalify: 2.0.1
+ dev: true
+
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
@@ -2059,6 +2115,14 @@ packages:
resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
dev: false
+ /jsonfile@6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
+ dev: true
+
/jszip@2.7.0:
resolution: {integrity: sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==}
dependencies:
@@ -2203,6 +2267,10 @@ packages:
kind-of: 6.0.3
dev: true
+ /minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ dev: true
+
/mitt@3.0.0:
resolution: {integrity: sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==}
dev: true
@@ -2213,7 +2281,6 @@ packages:
/moment@2.29.4:
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
- dev: true
/monaco-editor@0.43.0:
resolution: {integrity: sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q==}
@@ -2270,7 +2337,7 @@ packages:
dependencies:
hosted-git-info: 4.1.0
is-core-module: 2.12.0
- semver: 7.5.0
+ semver: 7.6.2
validate-npm-package-license: 3.0.4
dev: true
@@ -2451,7 +2518,7 @@ packages:
engines: {node: '>=6'}
dev: true
- /puppeteer-core@19.11.1(typescript@5.0.4):
+ /puppeteer-core@19.11.1(typescript@5.4.5):
resolution: {integrity: sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA==}
engines: {node: '>=14.14.0'}
peerDependencies:
@@ -2460,7 +2527,7 @@ packages:
typescript:
optional: true
dependencies:
- '@puppeteer/browsers': 0.5.0(typescript@5.0.4)
+ '@puppeteer/browsers': 0.5.0(typescript@5.4.5)
chromium-bidi: 0.4.7(devtools-protocol@0.0.1107588)
cross-fetch: 3.1.5
debug: 4.3.4
@@ -2469,7 +2536,7 @@ packages:
https-proxy-agent: 5.0.1
proxy-from-env: 1.1.0
tar-fs: 2.1.1
- typescript: 5.0.4
+ typescript: 5.4.5
unbzip2-stream: 1.4.3
ws: 8.13.0
transitivePeerDependencies:
@@ -2624,6 +2691,12 @@ packages:
lru-cache: 6.0.0
dev: true
+ /semver@7.6.2:
+ resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dev: true
+
/shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -2698,7 +2771,6 @@ packages:
resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==}
dependencies:
'@types/node': 18.16.3
- dev: true
/string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
@@ -2892,6 +2964,18 @@ packages:
engines: {node: '>=8'}
dev: true
+ /ts-patch@3.1.2:
+ resolution: {integrity: sha512-n58F5AqjUMdp9RAKq+E1YBkmONltPVbt1nN+wrmZXoYZek6QcvaTuqvKMhYhr5BxtC53kD/exxIPA1cP1RQxsA==}
+ hasBin: true
+ dependencies:
+ chalk: 4.1.2
+ global-prefix: 3.0.0
+ minimist: 1.2.8
+ resolve: 1.22.2
+ semver: 7.6.2
+ strip-ansi: 6.0.1
+ dev: true
+
/tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
@@ -2901,14 +2985,14 @@ packages:
dev: true
optional: true
- /tsutils@3.21.0(typescript@5.0.4):
+ /tsutils@3.21.0(typescript@5.4.5):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
peerDependencies:
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
dependencies:
tslib: 1.14.1
- typescript: 5.0.4
+ typescript: 5.4.5
dev: true
/tsx@3.12.7:
@@ -2952,7 +3036,6 @@ packages:
/type-fest@3.9.0:
resolution: {integrity: sha512-hR8JP2e8UiH7SME5JZjsobBlEiatFoxpzCP+R3ZeCo7kAaG1jXQE5X/buLzogM6GJu8le9Y4OcfNuIQX0rZskA==}
engines: {node: '>=14.16'}
- dev: true
/typed-emitter@2.1.0:
resolution: {integrity: sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==}
@@ -2960,9 +3043,18 @@ packages:
rxjs: 7.8.1
dev: true
- /typescript@5.0.4:
- resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
- engines: {node: '>=12.20'}
+ /typescript-transform-paths@3.4.7(typescript@5.4.5):
+ resolution: {integrity: sha512-1Us1kdkdfKd2unbkBAOV2HHRmbRBYpSuk9nJ7cLD2hP4QmfToiM/VpxNlhJc1eezVwVqSKSBjNSzZsK/fWR/9A==}
+ peerDependencies:
+ typescript: '>=3.6.5'
+ dependencies:
+ minimatch: 3.1.2
+ typescript: 5.4.5
+ dev: true
+
+ /typescript@5.4.5:
+ resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
+ engines: {node: '>=14.17'}
hasBin: true
dev: true
@@ -2973,6 +3065,11 @@ packages:
through: 2.3.8
dev: true
+ /universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+ dev: true
+
/uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
dependencies:
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 00000000..9bec5ba5
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,2 @@
+packages:
+ - packages/*
diff --git a/src/Vencord.ts b/src/Vencord.ts
index f7b2ae13..3dca3937 100644
--- a/src/Vencord.ts
+++ b/src/Vencord.ts
@@ -17,6 +17,7 @@
*/
export * as Api from "./api";
+export * as Components from "./components";
export * as Plugins from "./plugins";
export * as Util from "./utils";
export * as QuickCss from "./utils/quickCss";
diff --git a/src/api/Notifications/Notifications.tsx b/src/api/Notifications/Notifications.tsx
index 60256467..1350e5bd 100644
--- a/src/api/Notifications/Notifications.tsx
+++ b/src/api/Notifications/Notifications.tsx
@@ -100,6 +100,7 @@ export async function showNotification(data: NotificationData) {
const n = new Notification(title, {
body,
icon,
+ // @ts-expect-error ts is drunk
image
});
n.onclick = onClick;
diff --git a/src/components/ExpandableHeader.tsx b/src/components/ExpandableHeader.tsx
index 1cbce4f2..84b06586 100644
--- a/src/components/ExpandableHeader.tsx
+++ b/src/components/ExpandableHeader.tsx
@@ -16,10 +16,12 @@
* along with this program. If not, see .
*/
+import "./ExpandableHeader.css";
+
import { classNameFactory } from "@api/Styles";
import { Text, Tooltip, useState } from "@webpack/common";
-export const cl = classNameFactory("vc-expandableheader-");
-import "./ExpandableHeader.css";
+
+const cl = classNameFactory("vc-expandableheader-");
export interface ExpandableHeaderProps {
onMoreClick?: () => void;
@@ -31,7 +33,7 @@ export interface ExpandableHeaderProps {
buttons?: React.ReactNode[];
}
-export default function ExpandableHeader({ children, onMoreClick, buttons, moreTooltipText, defaultState = false, onDropDownClick, headerText }: ExpandableHeaderProps) {
+export function ExpandableHeader({ children, onMoreClick, buttons, moreTooltipText, defaultState = false, onDropDownClick, headerText }: ExpandableHeaderProps) {
const [showContent, setShowContent] = useState(defaultState);
return (
diff --git a/src/components/VencordSettings/PatchHelperTab.tsx b/src/components/VencordSettings/PatchHelperTab.tsx
index 9e2980e7..e09a1dbf 100644
--- a/src/components/VencordSettings/PatchHelperTab.tsx
+++ b/src/components/VencordSettings/PatchHelperTab.tsx
@@ -16,7 +16,6 @@
* along with this program. If not, see .
*/
-import { CheckedTextInput } from "@components/CheckedTextInput";
import { CodeBlock } from "@components/CodeBlock";
import { debounce } from "@shared/debounce";
import { Margins } from "@utils/margins";
@@ -47,7 +46,7 @@ const findCandidates = debounce(function ({ find, setModule, setError }) {
interface ReplacementComponentProps {
module: [id: number, factory: Function];
- match: string | RegExp;
+ match: string;
replacement: string | ReplaceFn;
setReplacementError(error: any): void;
}
@@ -58,7 +57,13 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
const [patchedCode, matchResult, diff] = React.useMemo(() => {
const src: string = fact.toString().replaceAll("\n", "");
- const canonicalMatch = canonicalizeMatch(match);
+
+ try {
+ new RegExp(match);
+ } catch (e) {
+ return ["", [], []];
+ }
+ const canonicalMatch = canonicalizeMatch(new RegExp(match));
try {
const canonicalReplace = canonicalizeReplace(replacement, "YourPlugin");
var patched = src.replace(canonicalMatch, canonicalReplace as string);
@@ -286,6 +291,7 @@ function PatchHelper() {
const [module, setModule] = React.useState<[number, Function]>();
const [findError, setFindError] = React.useState();
+ const [matchError, setMatchError] = React.useState();
const code = React.useMemo(() => {
return `
@@ -300,20 +306,16 @@ function PatchHelper() {
}, [parsedFind, match, replacement]);
function onFindChange(v: string) {
- setFindError(void 0);
setFind(v);
- }
- function onFindBlur() {
try {
- let parsedFind = find as string | RegExp;
- if (/^\/.+?\/$/.test(find)) parsedFind = new RegExp(find.slice(1, -1));
+ let parsedFind = v as string | RegExp;
+ if (/^\/.+?\/$/.test(v)) parsedFind = new RegExp(v.slice(1, -1));
setFindError(void 0);
- setFind(find);
setParsedFind(parsedFind);
- if (find.length) {
+ if (v.length) {
findCandidates({ find: parsedFind, setModule, setError: setFindError });
}
} catch (e: any) {
@@ -322,12 +324,13 @@ function PatchHelper() {
}
function onMatchChange(v: string) {
+ setMatch(v);
+
try {
new RegExp(v);
- setFindError(void 0);
- setMatch(v);
+ setMatchError(void 0);
} catch (e: any) {
- setFindError((e as Error).message);
+ setMatchError((e as Error).message);
}
}
@@ -346,21 +349,15 @@ function PatchHelper() {
type="text"
value={find}
onChange={onFindChange}
- onBlur={onFindBlur}
error={findError}
/>
match
- {
- try {
- return (new RegExp(v), true);
- } catch (e) {
- return (e as Error).message;
- }
- }}
+ error={matchError}
/>
@@ -374,7 +371,7 @@ function PatchHelper() {
{module && (
diff --git a/src/components/index.ts b/src/components/index.ts
new file mode 100644
index 00000000..38e610fd
--- /dev/null
+++ b/src/components/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+export * from "./Badge";
+export * from "./CheckedTextInput";
+export * from "./CodeBlock";
+export * from "./DonateButton";
+export { default as ErrorBoundary } from "./ErrorBoundary";
+export * from "./ErrorCard";
+export * from "./ExpandableHeader";
+export * from "./Flex";
+export * from "./Heart";
+export * from "./Icons";
+export * from "./Link";
+export * from "./Switch";
diff --git a/src/modules.d.ts b/src/modules.d.ts
index 24f34664..48979925 100644
--- a/src/modules.d.ts
+++ b/src/modules.d.ts
@@ -20,7 +20,7 @@
///
declare module "~plugins" {
- const plugins: Record;
+ const plugins: Record;
export default plugins;
}
diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx
index 5a73188b..8b9fb887 100644
--- a/src/plugins/_core/settings.tsx
+++ b/src/plugins/_core/settings.tsx
@@ -55,7 +55,6 @@ export default definePlugin({
}
]
},
- // Discord Canary
{
find: "Messages.ACTIVITY_SETTINGS",
replacement: {
diff --git a/src/plugins/customidle/README.md b/src/plugins/customidle/README.md
new file mode 100644
index 00000000..63bf87d8
--- /dev/null
+++ b/src/plugins/customidle/README.md
@@ -0,0 +1,5 @@
+# CustomIdle
+
+Lets you change the time until your status gets automatically set to idle. You can also prevent idling altogether.
+
+![Plugin Configuration](https://github.com/Vendicated/Vencord/assets/45801973/4e5259b2-18e0-42e5-b69f-efc672ce1e0b)
diff --git a/src/plugins/customidle/index.ts b/src/plugins/customidle/index.ts
new file mode 100644
index 00000000..a59bbcb0
--- /dev/null
+++ b/src/plugins/customidle/index.ts
@@ -0,0 +1,94 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { Notices } from "@api/index";
+import { definePluginSettings } from "@api/Settings";
+import { makeRange } from "@components/PluginSettings/components";
+import { Devs } from "@utils/constants";
+import definePlugin, { OptionType } from "@utils/types";
+import { FluxDispatcher } from "@webpack/common";
+
+const settings = definePluginSettings({
+ idleTimeout: {
+ description: "Minutes before Discord goes idle (0 to disable auto-idle)",
+ type: OptionType.SLIDER,
+ markers: makeRange(0, 60, 5),
+ default: 10,
+ stickToMarkers: false,
+ restartNeeded: true // Because of the setInterval patch
+ },
+ remainInIdle: {
+ description: "When you come back to Discord, remain idle until you confirm you want to go online",
+ type: OptionType.BOOLEAN,
+ default: true
+ }
+});
+
+export default definePlugin({
+ name: "CustomIdle",
+ description: "Allows you to set the time before Discord goes idle (or disable auto-idle)",
+ authors: [Devs.newwares],
+ settings,
+ patches: [
+ {
+ find: "IDLE_DURATION:function(){return",
+ replacement: {
+ match: /(IDLE_DURATION:function\(\){return )\i/,
+ replace: "$1$self.getIdleTimeout()"
+ }
+ },
+ {
+ find: 'type:"IDLE",idle:',
+ replacement: [
+ {
+ match: /Math\.min\((\i\.AfkTimeout\.getSetting\(\)\*\i\.default\.Millis\.SECOND),\i\.IDLE_DURATION\)/,
+ replace: "$1" // Decouple idle from afk (phone notifications will remain at user setting or 10 min maximum)
+ },
+ {
+ match: /\i\.default\.dispatch\({type:"IDLE",idle:!1}\)/,
+ replace: "$self.handleOnline()"
+ },
+ {
+ match: /(setInterval\(\i,\.25\*)\i\.IDLE_DURATION/,
+ replace: "$1$self.getIntervalDelay()" // For web installs
+ }
+ ]
+ }
+ ],
+
+ getIntervalDelay() {
+ return Math.min(6e5, this.getIdleTimeout());
+ },
+
+ handleOnline() {
+ if (!settings.store.remainInIdle) {
+ FluxDispatcher.dispatch({
+ type: "IDLE",
+ idle: false
+ });
+ return;
+ }
+
+ const backOnlineMessage = "Welcome back! Click the button to go online. Click the X to stay idle until reload.";
+ if (
+ Notices.currentNotice?.[1] === backOnlineMessage ||
+ Notices.noticesQueue.some(([, noticeMessage]) => noticeMessage === backOnlineMessage)
+ ) return;
+
+ Notices.showNotice(backOnlineMessage, "Exit idle", () => {
+ Notices.popNotice();
+ FluxDispatcher.dispatch({
+ type: "IDLE",
+ idle: false
+ });
+ });
+ },
+
+ getIdleTimeout() { // milliseconds, default is 6e5
+ const { idleTimeout } = settings.store;
+ return idleTimeout === 0 ? Infinity : idleTimeout * 60000;
+ }
+});
diff --git a/src/plugins/decor/lib/stores/AuthorizationStore.tsx b/src/plugins/decor/lib/stores/AuthorizationStore.tsx
index e31b1f43..ba71da99 100644
--- a/src/plugins/decor/lib/stores/AuthorizationStore.tsx
+++ b/src/plugins/decor/lib/stores/AuthorizationStore.tsx
@@ -9,7 +9,6 @@ import { proxyLazy } from "@utils/lazy";
import { Logger } from "@utils/Logger";
import { openModal } from "@utils/modal";
import { OAuth2AuthorizeModal, showToast, Toasts, UserStore, zustandCreate, zustandPersist } from "@webpack/common";
-import type { StateStorage } from "zustand/middleware";
import { AUTHORIZE_URL, CLIENT_ID } from "../constants";
@@ -23,7 +22,7 @@ interface AuthorizationState {
isAuthorized: () => boolean;
}
-const indexedDBStorage: StateStorage = {
+const indexedDBStorage = {
async getItem(name: string): Promise {
return DataStore.get(name).then(v => v ?? null);
},
@@ -36,9 +35,9 @@ const indexedDBStorage: StateStorage = {
};
// TODO: Move switching accounts subscription inside the store?
-export const useAuthorizationStore = proxyLazy(() => zustandCreate(
+export const useAuthorizationStore = proxyLazy(() => zustandCreate(
zustandPersist(
- (set, get) => ({
+ (set: any, get: any) => ({
token: null,
tokens: {},
init: () => { set({ token: get().tokens[UserStore.getCurrentUser().id] ?? null }); },
@@ -91,7 +90,7 @@ export const useAuthorizationStore = proxyLazy(() => zustandCreate !!get().token,
- }),
+ } as AuthorizationState),
{
name: "decor-auth",
getStorage: () => indexedDBStorage,
diff --git a/src/plugins/decor/lib/stores/CurrentUserDecorationsStore.ts b/src/plugins/decor/lib/stores/CurrentUserDecorationsStore.ts
index 1485a743..e2bba6c0 100644
--- a/src/plugins/decor/lib/stores/CurrentUserDecorationsStore.ts
+++ b/src/plugins/decor/lib/stores/CurrentUserDecorationsStore.ts
@@ -21,7 +21,7 @@ interface UserDecorationsState {
clear: () => void;
}
-export const useCurrentUserDecorationsStore = proxyLazy(() => zustandCreate((set, get) => ({
+export const useCurrentUserDecorationsStore = proxyLazy(() => zustandCreate((set: any, get: any) => ({
decorations: [],
selectedDecoration: null,
async fetch() {
@@ -53,4 +53,4 @@ export const useCurrentUserDecorationsStore = proxyLazy(() => zustandCreate set({ decorations: [], selectedDecoration: null })
-})));
+} as UserDecorationsState)));
diff --git a/src/plugins/decor/lib/stores/UsersDecorationsStore.ts b/src/plugins/decor/lib/stores/UsersDecorationsStore.ts
index b29945f8..53aa33e6 100644
--- a/src/plugins/decor/lib/stores/UsersDecorationsStore.ts
+++ b/src/plugins/decor/lib/stores/UsersDecorationsStore.ts
@@ -30,7 +30,7 @@ interface UsersDecorationsState {
set: (userId: string, decoration: string | null) => void;
}
-export const useUsersDecorationsStore = proxyLazy(() => zustandCreate((set, get) => ({
+export const useUsersDecorationsStore = proxyLazy(() => zustandCreate((set: any, get: any) => ({
usersDecorations: new Map(),
fetchQueue: new Set(),
bulkFetch: debounce(async () => {
@@ -40,7 +40,7 @@ export const useUsersDecorationsStore = proxyLazy(() => zustandCreate zustandCreate(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null);
diff --git a/src/plugins/decor/ui/components/DecorSection.tsx b/src/plugins/decor/ui/components/DecorSection.tsx
index f11a87a5..ff044f8c 100644
--- a/src/plugins/decor/ui/components/DecorSection.tsx
+++ b/src/plugins/decor/ui/components/DecorSection.tsx
@@ -15,7 +15,7 @@ import { openChangeDecorationModal } from "../modals/ChangeDecorationModal";
const CustomizationSection = findByCodeLazy(".customizationSectionBackground");
-interface DecorSectionProps {
+export interface DecorSectionProps {
hideTitle?: boolean;
hideDivider?: boolean;
noMargin?: boolean;
diff --git a/src/plugins/friendsSince/index.tsx b/src/plugins/friendsSince/index.tsx
index b3bd91b4..08b9aef8 100644
--- a/src/plugins/friendsSince/index.tsx
+++ b/src/plugins/friendsSince/index.tsx
@@ -7,6 +7,8 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord";
+import { Logger } from "@utils/Logger";
+import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { Heading, React, RelationshipStore, Text } from "@webpack/common";
@@ -22,6 +24,7 @@ export default definePlugin({
description: "Shows when you became friends with someone in the user popout",
authors: [Devs.Elvyra],
patches: [
+ // User popup
{
find: ".AnalyticsSections.USER_PROFILE}};",
replacement: {
@@ -29,16 +32,34 @@ export default definePlugin({
replace: "$&,$self.friendsSince({ userId: $1 })"
}
},
+ // User DMs "User Profile" popup in the right
{
find: ".UserPopoutUpsellSource.PROFILE_PANEL,",
replacement: {
match: /\i.default,\{userId:(\i)}\)/,
replace: "$&,$self.friendsSince({ userId: $1 })"
}
+ },
+ // User Profile Modal
+ {
+ find: ".userInfoSectionHeader,",
+ replacement: {
+ match: /(\.Messages\.USER_PROFILE_MEMBER_SINCE.+?userId:(.+?),textClassName:)(\i\.userInfoText)}\)/,
+ replace: (_, rest, userId, textClassName) => `${rest}!$self.getFriendSince(${userId}) ? ${textClassName} : void 0 }), $self.friendsSince({ userId: ${userId}, textClassName: ${textClassName} })`
+ }
}
],
- friendsSince: ErrorBoundary.wrap(({ userId }: { userId: string; }) => {
+ getFriendSince(userId: string) {
+ try {
+ return RelationshipStore.getSince(userId);
+ } catch (err) {
+ new Logger("FriendsSince").error(err);
+ return null;
+ }
+ },
+
+ friendsSince: ErrorBoundary.wrap(({ userId, textClassName }: { userId: string; textClassName?: string; }) => {
const friendsSince = RelationshipStore.getSince(userId);
if (!friendsSince) return null;
@@ -61,7 +82,7 @@ export default definePlugin({
)}
-
+
{getCreatedAtDate(friendsSince, locale.getLocale())}
diff --git a/src/plugins/lastfm/index.tsx b/src/plugins/lastfm/index.tsx
index 1213ece2..02fd694f 100644
--- a/src/plugins/lastfm/index.tsx
+++ b/src/plugins/lastfm/index.tsx
@@ -114,6 +114,11 @@ const settings = definePluginSettings({
type: OptionType.BOOLEAN,
default: false,
},
+ shareSong: {
+ description: "show link to song on last.fm",
+ type: OptionType.BOOLEAN,
+ default: true,
+ },
hideWithSpotify: {
description: "hide last.fm presence if spotify is running",
type: OptionType.BOOLEAN,
@@ -295,12 +300,7 @@ export default definePlugin({
large_text: trackData.album || undefined,
};
- const buttons: ActivityButton[] = [
- {
- label: "View Song",
- url: trackData.url,
- },
- ];
+ const buttons: ActivityButton[] = [];
if (settings.store.shareUsername)
buttons.push({
@@ -308,6 +308,12 @@ export default definePlugin({
url: `https://www.last.fm/user/${settings.store.username}`,
});
+ if (settings.store.shareSong)
+ buttons.push({
+ label: "View Song",
+ url: trackData.url,
+ });
+
const statusName = (() => {
switch (settings.store.nameFormat) {
case NameFormat.ArtistFirst:
@@ -333,7 +339,7 @@ export default definePlugin({
state: trackData.artist,
assets,
- buttons: buttons.map(v => v.label),
+ buttons: buttons.length ? buttons.map(v => v.label) : undefined,
metadata: {
button_urls: buttons.map(v => v.url),
},
diff --git a/src/plugins/messageLinkEmbeds/index.tsx b/src/plugins/messageLinkEmbeds/index.tsx
index 287d58bb..21334c63 100644
--- a/src/plugins/messageLinkEmbeds/index.tsx
+++ b/src/plugins/messageLinkEmbeds/index.tsx
@@ -227,10 +227,8 @@ function MessageEmbedAccessory({ message }: { message: Message; }) {
const accessories = [] as (JSX.Element | null)[];
- let match = null as RegExpMatchArray | null;
- while ((match = messageLinkRegex.exec(message.content!)) !== null) {
- const [_, channelID, messageID] = match;
- if (embeddedBy.includes(messageID)) {
+ for (const [_, channelID, messageID] of message.content!.matchAll(messageLinkRegex)) {
+ if (embeddedBy.includes(messageID) || embeddedBy.length > 2) {
continue;
}
@@ -378,9 +376,6 @@ export default definePlugin({
if (!messageLinkRegex.test(props.message.content))
return null;
- // need to reset the regex because it's global
- messageLinkRegex.lastIndex = 0;
-
return (
perms.includes(perm)) ||
(tag.condition?.(message!, user, channel))
diff --git a/src/plugins/permissionsViewer/components/UserPermissions.tsx b/src/plugins/permissionsViewer/components/UserPermissions.tsx
index bcd6bdf0..869a6a1e 100644
--- a/src/plugins/permissionsViewer/components/UserPermissions.tsx
+++ b/src/plugins/permissionsViewer/components/UserPermissions.tsx
@@ -17,7 +17,7 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
-import ExpandableHeader from "@components/ExpandableHeader";
+import { ExpandableHeader } from "@components/ExpandableHeader";
import { classes } from "@utils/misc";
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
import { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
diff --git a/src/plugins/replaceGoogleSearch/index.tsx b/src/plugins/replaceGoogleSearch/index.tsx
index 1b1a761f..dff593a3 100644
--- a/src/plugins/replaceGoogleSearch/index.tsx
+++ b/src/plugins/replaceGoogleSearch/index.tsx
@@ -15,7 +15,7 @@ const DefaultEngines = {
DuckDuckGo: "https://duckduckgo.com/",
Bing: "https://www.bing.com/search?q=",
Yahoo: "https://search.yahoo.com/search?p=",
- Github: "https://github.com/search?q=",
+ GitHub: "https://github.com/search?q=",
Kagi: "https://kagi.com/search?q=",
Yandex: "https://yandex.com/search/?text=",
AOL: "https://search.aol.com/aol/search?q=",
diff --git a/src/plugins/resurrectHome/index.tsx b/src/plugins/resurrectHome/index.tsx
index 2042ed9c..70827e08 100644
--- a/src/plugins/resurrectHome/index.tsx
+++ b/src/plugins/resurrectHome/index.tsx
@@ -135,7 +135,7 @@ export default definePlugin({
find: '"MessageActionCreators"',
replacement: {
match: /(?<=focusMessage\(\i\){.+?)(?=focus:{messageId:(\i)})/,
- replace: "before:$1,"
+ replace: "after:$1,"
}
},
// Force Server Home instead of Server Guide
diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index e73bce82..2ae74c38 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -20,7 +20,7 @@ import "./style.css";
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
import ErrorBoundary from "@components/ErrorBoundary";
-import ExpandableHeader from "@components/ExpandableHeader";
+import { ExpandableHeader } from "@components/ExpandableHeader";
import { OpenExternalIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx
index 09aa2302..f08bc2d1 100644
--- a/src/plugins/showHiddenChannels/index.tsx
+++ b/src/plugins/showHiddenChannels/index.tsx
@@ -436,7 +436,7 @@ export default definePlugin({
},
},
{
- find: ".shouldCloseDefaultModals",
+ find: 'className:"channelMention",children',
replacement: {
// Show inside voice channel instead of trying to join them when clicking on a channel mention
match: /(?<=getChannel\(\i\);if\(null!=(\i))(?=.{0,100}?selectVoiceChannel)/,
diff --git a/src/plugins/startupTimings/index.tsx b/src/plugins/startupTimings/index.tsx
index cf366df3..5051fdf4 100644
--- a/src/plugins/startupTimings/index.tsx
+++ b/src/plugins/startupTimings/index.tsx
@@ -28,7 +28,7 @@ export default definePlugin({
patches: [{
find: "Messages.ACTIVITY_SETTINGS",
replacement: {
- match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+}\))/,
+ match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+}\)}\))/,
replace: (_, commaOrSemi, settings, elements) => "" +
`${commaOrSemi}${settings}?.[0]==="CHANGELOG"` +
`&&${elements}.push({section:"StartupTimings",label:"Startup Timings",element:$self.StartupTimingPage})`
diff --git a/src/plugins/vcDoubleClick/index.ts b/src/plugins/vcDoubleClick/index.ts
index a55ac7b6..8d4cae6a 100644
--- a/src/plugins/vcDoubleClick/index.ts
+++ b/src/plugins/vcDoubleClick/index.ts
@@ -48,7 +48,7 @@ export default definePlugin({
})),
{
// channel mentions
- find: ".shouldCloseDefaultModals",
+ find: 'className:"channelMention",children',
replacement: {
match: /onClick:(\i)(?=,.{0,30}className:"channelMention".+?(\i)\.inContent)/,
replace: (_, onClick, props) => ""
diff --git a/src/plugins/viewIcons/index.tsx b/src/plugins/viewIcons/index.tsx
index 104252f6..359365ee 100644
--- a/src/plugins/viewIcons/index.tsx
+++ b/src/plugins/viewIcons/index.tsx
@@ -212,8 +212,7 @@ export default definePlugin({
},
// Group DMs top small & large icon
{
- find: ".recipients.length>=2",
- all: true,
+ find: /\.recipients\.length>=2(?! `${m},onClick:()=>$self.openImage(${iconUrl})`
diff --git a/src/utils/constants.ts b/src/utils/constants.ts
index 95f4022c..fe2e875b 100644
--- a/src/utils/constants.ts
+++ b/src/utils/constants.ts
@@ -424,6 +424,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
name: "Av32000",
id: 593436735380127770n,
},
+ Noxillio: {
+ name: "Noxillio",
+ id: 138616536502894592n,
+ },
Kyuuhachi: {
name: "Kyuuhachi",
id: 236588665420251137n,
diff --git a/src/utils/index.ts b/src/utils/index.ts
index ea4adce4..62f3f6e9 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -23,9 +23,11 @@ export * from "./constants";
export * from "./discord";
export * from "./guards";
export * from "./lazy";
+export * from "./lazyReact";
export * from "./localStorage";
export * from "./Logger";
export * from "./margins";
+export * from "./mergeDefaults";
export * from "./misc";
export * from "./modal";
export * from "./onlyOnce";
diff --git a/src/utils/types.ts b/src/utils/types.ts
index 8f2ee863..6e152419 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -244,7 +244,7 @@ export interface PluginSettingSliderDef {
stickToMarkers?: boolean;
}
-interface IPluginOptionComponentProps {
+export interface IPluginOptionComponentProps {
/**
* Run this when the value changes.
*
diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts
index 20065093..84fe03b4 100644
--- a/src/webpack/common/utils.ts
+++ b/src/webpack/common/utils.ts
@@ -136,10 +136,10 @@ waitFor(["open", "saveAccountChanges"], m => SettingsRouter = m);
export const { Permissions: PermissionsBits } = findLazy(m => typeof m.Permissions?.ADMINISTRATOR === "bigint") as { Permissions: t.PermissionsBits; };
-export const zustandCreate: typeof import("zustand").default = findByCodeLazy("will be removed in v4");
+export const zustandCreate = findByCodeLazy("will be removed in v4");
const persistFilter = filters.byCode("[zustand persist middleware]");
-export const { persist: zustandPersist }: typeof import("zustand/middleware") = findLazy(m => m.persist && persistFilter(m.persist));
+export const { persist: zustandPersist } = findLazy(m => m.persist && persistFilter(m.persist));
export const MessageActions = findByPropsLazy("editMessage", "sendMessage");
export const UserProfileActions = findByPropsLazy("openUserProfileModal", "closeUserProfileModal");
diff --git a/src/webpack/patchWebpack.ts b/src/webpack/patchWebpack.ts
index 6f334b39..98c8b696 100644
--- a/src/webpack/patchWebpack.ts
+++ b/src/webpack/patchWebpack.ts
@@ -122,7 +122,7 @@ Object.defineProperty(Function.prototype, "m", {
// When using react devtools or other extensions, we may also catch their webpack here.
// This ensures we actually got the right one
const { stack } = new Error();
- if (stack?.includes("discord.com") || stack?.includes("discordapp.com")) {
+ if ((stack?.includes("discord.com") || stack?.includes("discordapp.com")) && !Array.isArray(v)) {
logger.info("Found Webpack module factory", stack.match(/\/assets\/(.+?\.js)/)?.[1] ?? "");
patchFactories(v);
}
diff --git a/tsconfig.json b/tsconfig.json
index 4db1319e..9f7f0e82 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,6 +20,9 @@
"jsx": "preserve",
"baseUrl": "./src/",
"paths": {
+ "@main/*": [
+ "./main/*"
+ ],
"@api/*": [
"./api/*"
],
@@ -41,7 +44,14 @@
"@webpack": [
"./webpack/webpack"
]
- }
+ },
+ "plugins": [
+ // Transform paths in output .d.ts files (Include this line if you output declarations files)
+ {
+ "transform": "typescript-transform-paths",
+ "afterDeclarations": true
+ }
+ ]
},
"include": [
"src/**/*"