Merge remote-tracking branch 'upstream/dev'

This commit is contained in:
thororen1234 2024-05-20 15:39:21 -04:00
commit 9d0550bf79
43 changed files with 644 additions and 248 deletions

1
.npmrc
View file

@ -1 +1,2 @@
strict-peer-dependencies=false
package-manager-strict=false

View file

@ -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"
},

7
packages/vencord-types/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
*
!.*ignore
!package.json
!*.md
!prepare.ts
!index.d.ts
!globals.d.ts

View file

@ -0,0 +1,4 @@
node_modules
prepare.ts
.gitignore
HOW2PUB.md

View file

@ -0,0 +1,5 @@
# How to publish
1. run `pnpm generateTypes` in the project root
2. bump package.json version
3. npm publish

View file

@ -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
```

24
packages/vencord-types/globals.d.ts vendored Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
*/
declare global {
export var VencordNative: typeof import("./VencordNative").default;
export var Vencord: typeof import("./Vencord");
}
export { };

5
packages/vencord-types/index.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
/* eslint-disable */
/// <reference path="Vencord.d.ts" />
/// <reference path="globals.d.ts" />
/// <reference path="modules.d.ts" />

View file

@ -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"
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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);

View file

@ -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:

2
pnpm-workspace.yaml Normal file
View file

@ -0,0 +1,2 @@
packages:
- packages/*

View file

@ -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";

View file

@ -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;

View file

@ -16,10 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 (

View file

@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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<string>();
const [matchError, setMatchError] = React.useState<string>();
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}
/>
<Forms.FormTitle className={Margins.top8}>match</Forms.FormTitle>
<CheckedTextInput
<TextInput
type="text"
value={match}
onChange={onMatchChange}
validate={v => {
try {
return (new RegExp(v), true);
} catch (e) {
return (e as Error).message;
}
}}
error={matchError}
/>
<div className={Margins.top8} />
@ -374,7 +371,7 @@ function PatchHelper() {
{module && (
<ReplacementComponent
module={module}
match={new RegExp(match)}
match={match}
replacement={replacement}
setReplacementError={setReplacementError}
/>

18
src/components/index.ts Normal file
View file

@ -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";

2
src/modules.d.ts vendored
View file

@ -20,7 +20,7 @@
/// <reference types="standalone-electron-types"/>
declare module "~plugins" {
const plugins: Record<string, import("@utils/types").Plugin>;
const plugins: Record<string, import("./utils/types").Plugin>;
export default plugins;
}

View file

@ -55,7 +55,6 @@ export default definePlugin({
}
]
},
// Discord Canary
{
find: "Messages.ACTIVITY_SETTINGS",
replacement: {

View file

@ -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)

View file

@ -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;
}
});

View file

@ -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<string | null> {
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<AuthorizationState>(
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<Authorization
));
},
isAuthorized: () => !!get().token,
}),
} as AuthorizationState),
{
name: "decor-auth",
getStorage: () => indexedDBStorage,

View file

@ -21,7 +21,7 @@ interface UserDecorationsState {
clear: () => void;
}
export const useCurrentUserDecorationsStore = proxyLazy(() => zustandCreate<UserDecorationsState>((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<User
useUsersDecorationsStore.getState().set(UserStore.getCurrentUser().id, decoration ? decorationToAsset(decoration) : null);
},
clear: () => set({ decorations: [], selectedDecoration: null })
})));
} as UserDecorationsState)));

View file

@ -30,7 +30,7 @@ interface UsersDecorationsState {
set: (userId: string, decoration: string | null) => void;
}
export const useUsersDecorationsStore = proxyLazy(() => zustandCreate<UsersDecorationsState>((set, get) => ({
export const useUsersDecorationsStore = proxyLazy(() => zustandCreate((set: any, get: any) => ({
usersDecorations: new Map<string, UserDecorationData>(),
fetchQueue: new Set(),
bulkFetch: debounce(async () => {
@ -40,7 +40,7 @@ export const useUsersDecorationsStore = proxyLazy(() => zustandCreate<UsersDecor
set({ fetchQueue: new Set() });
const fetchIds = Array.from(fetchQueue);
const fetchIds = [...fetchQueue];
const fetchedUsersDecorations = await getUsersDecorations(fetchIds);
const newUsersDecorations = new Map(usersDecorations);
@ -92,7 +92,7 @@ export const useUsersDecorationsStore = proxyLazy(() => zustandCreate<UsersDecor
newUsersDecorations.set(userId, { asset: decoration, fetchedAt: new Date() });
set({ usersDecorations: newUsersDecorations });
}
})));
} as UsersDecorationsState)));
export function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | null | undefined {
const [decorAvatarDecoration, setDecorAvatarDecoration] = useState<string | null>(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null);

View file

@ -15,7 +15,7 @@ import { openChangeDecorationModal } from "../modals/ChangeDecorationModal";
const CustomizationSection = findByCodeLazy(".customizationSectionBackground");
interface DecorSectionProps {
export interface DecorSectionProps {
hideTitle?: boolean;
hideDivider?: boolean;
noMargin?: boolean;

View file

@ -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({
<path d="M3 5v-.75C3 3.56 3.56 3 4.25 3s1.24.56 1.33 1.25C6.12 8.65 9.46 12 13 12h1a8 8 0 0 1 8 8 2 2 0 0 1-2 2 .21.21 0 0 1-.2-.15 7.65 7.65 0 0 0-1.32-2.3c-.15-.2-.42-.06-.39.17l.25 2c.02.15-.1.28-.25.28H9a2 2 0 0 1-2-2v-2.22c0-1.57-.67-3.05-1.53-4.37A15.85 15.85 0 0 1 3 5Z" />
</svg>
)}
<Text variant="text-sm/normal" className={clydeMoreInfo.body}>
<Text variant="text-sm/normal" className={classes(clydeMoreInfo.body, textClassName)}>
{getCreatedAtDate(friendsSince, locale.getLocale())}
</Text>
</div>

View file

@ -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),
},

View file

@ -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 (
<ErrorBoundary>
<MessageEmbedAccessory

View file

@ -354,6 +354,15 @@ export default definePlugin({
if (location === "chat" && !settings.tagSettings[tag.name].showInChat) continue;
if (location === "not-chat" && !settings.tagSettings[tag.name].showInNotChat) continue;
// If the owner tag is disabled, and the user is the owner of the guild,
// avoid adding other tags because the owner will always match the condition for them
if (
tag.name !== "OWNER" &&
GuildStore.getGuild(channel?.guild_id)?.ownerId === user.id &&
(location === "chat" && !settings.tagSettings.OWNER.showInChat) ||
(location === "not-chat" && !settings.tagSettings.OWNER.showInNotChat)
) continue;
if (
tag.permissions?.some(perm => perms.includes(perm)) ||
(tag.condition?.(message!, user, channel))

View file

@ -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";

View file

@ -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=",

View file

@ -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

View file

@ -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";

View file

@ -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)/,

View file

@ -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})`

View file

@ -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) => ""

View file

@ -212,8 +212,7 @@ export default definePlugin({
},
// Group DMs top small & large icon
{
find: ".recipients.length>=2",
all: true,
find: /\.recipients\.length>=2(?!<isMultiUserDM.{0,50})/,
replacement: {
match: /null==\i\.icon\?.+?src:(\(0,\i\.getChannelIconURL\).+?\))(?=[,}])/,
replace: (m, iconUrl) => `${m},onClick:()=>$self.openImage(${iconUrl})`

View file

@ -424,6 +424,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
name: "Av32000",
id: 593436735380127770n,
},
Noxillio: {
name: "Noxillio",
id: 138616536502894592n,
},
Kyuuhachi: {
name: "Kyuuhachi",
id: 236588665420251137n,

View file

@ -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";

View file

@ -244,7 +244,7 @@ export interface PluginSettingSliderDef {
stickToMarkers?: boolean;
}
interface IPluginOptionComponentProps {
export interface IPluginOptionComponentProps {
/**
* Run this when the value changes.
*

View file

@ -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");

View file

@ -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);
}

View file

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