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/**/*"