From c58b6025c287784a8c83bc17874a17ede3ea1726 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Mon, 17 Aug 2026 17:46:31 +0200 Subject: [PATCH 1/9] v1.15.2 --- package.json | 2 +- packages/discord-types/package.json | 2 +- packages/vencord-types/package.json | 4 +- pnpm-lock.yaml | 212 ++++++++++++++-------------- pnpm-workspace.yaml | 2 + 5 files changed, 112 insertions(+), 110 deletions(-) diff --git a/package.json b/package.json index 4319c61b7..090f0c104 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.15.1", + "version": "1.15.2", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/packages/discord-types/package.json b/packages/discord-types/package.json index 3d217ee41..a49fcf865 100644 --- a/packages/discord-types/package.json +++ b/packages/discord-types/package.json @@ -3,7 +3,7 @@ "author": "Vencord Contributors", "private": false, "description": "Typescript definitions for the webpack modules of the Discord Web app", - "version": "1.0.1", + "version": "1.0.2", "license": "LGPL-3.0-or-later", "types": "src/index.d.ts", "type": "module", diff --git a/packages/vencord-types/package.json b/packages/vencord-types/package.json index 89d64f3be..fcd902c50 100644 --- a/packages/vencord-types/package.json +++ b/packages/vencord-types/package.json @@ -1,7 +1,7 @@ { "name": "@vencord/types", "private": false, - "version": "1.14.15", + "version": "1.15.1", "description": "", "types": "index.d.ts", "scripts": { @@ -19,7 +19,7 @@ "dependencies": { "@types/lodash": "4.17.19", "@types/node": "^26.0.1", - "@vencord/discord-types": "^1.0.1", + "@vencord/discord-types": "^1.0.2", "highlight.js": "11.11.1", "moment": "^2.22.2", "ts-pattern": "^5.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ddf8750c1..740970430 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,7 +38,7 @@ importers: devDependencies: '@stylistic/eslint-plugin': specifier: ^5.10.0 - version: 5.10.0(eslint@10.6.0) + version: 5.10.0(eslint@10.6.0(supports-color@10.2.2)) '@types/chrome': specifier: ^0.2.0 version: 0.2.0 @@ -68,25 +68,25 @@ importers: version: 0.28.1 eslint: specifier: 10.6.0 - version: 10.6.0 + version: 10.6.0(supports-color@10.2.2) eslint-import-resolver-alias: specifier: ^1.1.2 - version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)) + version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)) eslint-plugin-path-alias: specifier: 2.1.0 - version: 2.1.0(patch_hash=87545cb13985b338c8fa2ea7b0a3c75c57ad7fbc81c56b38d6c9438329957727)(eslint@10.6.0) + version: 2.1.0(patch_hash=87545cb13985b338c8fa2ea7b0a3c75c57ad7fbc81c56b38d6c9438329957727)(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2) eslint-plugin-react: specifier: ^7.37.5 - version: 7.37.5(eslint@10.6.0) + version: 7.37.5(eslint@10.6.0(supports-color@10.2.2)) eslint-plugin-simple-header: specifier: ^1.2.1 - version: 1.2.2(eslint@10.6.0) + version: 1.2.2(eslint@10.6.0(supports-color@10.2.2)) eslint-plugin-simple-import-sort: specifier: ^13.0.0 - version: 13.0.0(eslint@10.6.0) + version: 13.0.0(eslint@10.6.0(supports-color@10.2.2)) eslint-plugin-unused-imports: specifier: ^4.4.1 - version: 4.4.1(@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0) + version: 4.4.1(@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2)) highlight.js: specifier: 11.11.1 version: 11.11.1 @@ -107,10 +107,10 @@ importers: version: 41.2.1 stylelint: specifier: ^17.14.0 - version: 17.14.0(typescript@6.0.3) + version: 17.14.0(supports-color@10.2.2)(typescript@6.0.3) stylelint-config-standard: specifier: ^40.0.0 - version: 40.0.0(stylelint@17.14.0(typescript@6.0.3)) + version: 40.0.0(stylelint@17.14.0(supports-color@10.2.2)(typescript@6.0.3)) svgo: specifier: ^4.0.1 version: 4.0.1 @@ -131,7 +131,7 @@ importers: version: 6.0.3 typescript-eslint: specifier: ^8.62.1 - version: 8.62.1(eslint@10.6.0)(typescript@6.0.3) + version: 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) typescript-transform-paths: specifier: ^3.5.6 version: 3.5.6(typescript@6.0.3) @@ -166,8 +166,8 @@ importers: specifier: 18.3.1 version: 18.3.1 '@vencord/discord-types': - specifier: ^1.0.1 - version: 1.0.1(@types/react@18.3.1) + specifier: ^1.0.2 + version: 1.0.2(@types/react@18.3.1) highlight.js: specifier: 11.11.1 version: 11.11.1 @@ -659,10 +659,10 @@ packages: '@vap/shiki@0.10.5': resolution: {integrity: sha512-5BHVGvQT8qonbLSASon5aQFQ18OZU4FxSl9tLSj6oJ0sap3KdMbYcfGq25M9zFZR1g1dJN7fgjmZXBIS5omIdw==} - '@vencord/discord-types@1.0.1': - resolution: {integrity: sha512-uSQMDUTo9hMFgOMykNtTMTxScSKVVUHHFCevktO3bMyaLh1s3iDMfIvUvqU1fBkmFwvMbmEYsUrztsVKKHvang==} + '@vencord/discord-types@1.0.2': + resolution: {integrity: sha512-nq3YZebbv085/FsFcKhoVBCs9U9QuAEPy1noL9x9Bb5B29TdhQqr/hJCcApSWjY8J299+tLi30LEe0YGo3yn0Q==} peerDependencies: - '@types/react': ^19.0.10 + '@types/react': 19.1.0 acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -2426,10 +2426,6 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - type-fest@5.7.0: resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} engines: {node: '>=20'} @@ -2738,17 +2734,17 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.6.0)': + '@eslint-community/eslint-utils@4.9.1(eslint@10.6.0(supports-color@10.2.2))': dependencies: - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.23.5': + '@eslint/config-array@0.23.5(supports-color@10.2.2)': dependencies: '@eslint/object-schema': 3.0.5 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.5 transitivePeerDependencies: - supports-color @@ -2837,11 +2833,11 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.6.0)': + '@stylistic/eslint-plugin@5.10.0(eslint@10.6.0(supports-color@10.2.2))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0(supports-color@10.2.2)) '@typescript-eslint/types': 8.58.2 - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -2915,15 +2911,15 @@ snapshots: dependencies: '@types/node': 26.0.1 - '@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.62.1(eslint@10.6.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.62.1 - '@typescript-eslint/type-utils': 8.62.1(eslint@10.6.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.62.1(eslint@10.6.0)(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.62.1 - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -2931,23 +2927,23 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.62.1 '@typescript-eslint/types': 8.62.1 - '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.62.1(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.62.1 - debug: 4.4.3 - eslint: 10.6.0 + debug: 4.4.3(supports-color@10.2.2) + eslint: 10.6.0(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.62.1(typescript@6.0.3)': + '@typescript-eslint/project-service@8.62.1(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.62.1(typescript@6.0.3) '@typescript-eslint/types': 8.62.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -2961,13 +2957,13 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.62.1(eslint@10.6.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.62.1 - '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.62.1(eslint@10.6.0)(typescript@6.0.3) - debug: 4.4.3 - eslint: 10.6.0 + '@typescript-eslint/typescript-estree': 8.62.1(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + debug: 4.4.3(supports-color@10.2.2) + eslint: 10.6.0(supports-color@10.2.2) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -2977,13 +2973,13 @@ snapshots: '@typescript-eslint/types@8.62.1': {} - '@typescript-eslint/typescript-estree@8.62.1(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.62.1(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.62.1(typescript@6.0.3) + '@typescript-eslint/project-service': 8.62.1(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/tsconfig-utils': 8.62.1(typescript@6.0.3) '@typescript-eslint/types': 8.62.1 '@typescript-eslint/visitor-keys': 8.62.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.5 semver: 7.8.5 tinyglobby: 0.2.17 @@ -2992,13 +2988,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.62.1(eslint@10.6.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0(supports-color@10.2.2)) '@typescript-eslint/scope-manager': 8.62.1 '@typescript-eslint/types': 8.62.1 - '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3) - eslint: 10.6.0 + '@typescript-eslint/typescript-estree': 8.62.1(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.6.0(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -3018,11 +3014,11 @@ snapshots: vscode-oniguruma: 1.7.0 vscode-textmate: 5.2.0 - '@vencord/discord-types@1.0.1(@types/react@18.3.1)': + '@vencord/discord-types@1.0.2(@types/react@18.3.1)': dependencies: '@types/react': 18.3.1 - moment: 2.30.1 - type-fest: 4.41.0 + moment: 2.22.2 + type-fest: 5.7.0 acorn-jsx@5.3.2(acorn@8.16.0): dependencies: @@ -3358,17 +3354,23 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debug@2.6.9: + debug@2.6.9(supports-color@10.2.2): dependencies: ms: 2.0.0 + optionalDependencies: + supports-color: 10.2.2 - debug@3.2.7: + debug@3.2.7(supports-color@10.2.2): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 - debug@4.4.3: + debug@4.4.3(supports-color@10.2.2): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 decode-uri-component@0.2.2: {} @@ -3663,40 +3665,40 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)): dependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2) - eslint-import-resolver-node@0.3.10: + eslint-import-resolver-node@0.3.10(supports-color@10.2.2): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@10.2.2) is-core-module: 2.16.2 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color - eslint-module-utils@2.13.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.6.0): + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@10.2.2))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@10.2.2) optionalDependencies: - '@typescript-eslint/parser': 8.62.1(eslint@10.6.0)(typescript@6.0.3) - eslint: 10.6.0 - eslint-import-resolver-node: 0.3.10 + '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.6.0(supports-color@10.2.2) + eslint-import-resolver-node: 0.3.10(supports-color@10.2.2) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@10.2.2) doctrine: 2.1.0 - eslint: 10.6.0 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.6.0) + eslint: 10.6.0(supports-color@10.2.2) + eslint-import-resolver-node: 0.3.10(supports-color@10.2.2) + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@10.2.2))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -3708,22 +3710,22 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.62.1(eslint@10.6.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-path-alias@2.1.0(patch_hash=87545cb13985b338c8fa2ea7b0a3c75c57ad7fbc81c56b38d6c9438329957727)(eslint@10.6.0): + eslint-plugin-path-alias@2.1.0(patch_hash=87545cb13985b338c8fa2ea7b0a3c75c57ad7fbc81c56b38d6c9438329957727)(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2): dependencies: - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) find-pkg: 2.0.0 get-tsconfig: 4.10.0 - nanomatch: 1.2.13 + nanomatch: 1.2.13(supports-color@10.2.2) transitivePeerDependencies: - supports-color - eslint-plugin-react@7.37.5(eslint@10.6.0): + eslint-plugin-react@7.37.5(eslint@10.6.0(supports-color@10.2.2)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -3731,7 +3733,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -3745,19 +3747,19 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-simple-header@1.2.2(eslint@10.6.0): + eslint-plugin-simple-header@1.2.2(eslint@10.6.0(supports-color@10.2.2)): dependencies: - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) - eslint-plugin-simple-import-sort@13.0.0(eslint@10.6.0): + eslint-plugin-simple-import-sort@13.0.0(eslint@10.6.0(supports-color@10.2.2)): dependencies: - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) - eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0): + eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2)): dependencies: - eslint: 10.6.0 + eslint: 10.6.0(supports-color@10.2.2) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)(typescript@6.0.3) + '@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) eslint-scope@9.1.2: dependencies: @@ -3772,11 +3774,11 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.6.0: + eslint@10.6.0(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.5 + '@eslint/config-array': 0.23.5(supports-color@10.2.2) '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.7.2 @@ -3786,7 +3788,7 @@ snapshots: '@types/estree': 1.0.9 ajv: 6.15.0 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) escape-string-regexp: 4.0.0 eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 @@ -4476,7 +4478,7 @@ snapshots: nanoid@5.1.16: {} - nanomatch@1.2.13: + nanomatch@1.2.13(supports-color@10.2.2): dependencies: arr-diff: 4.0.0 array-unique: 0.3.2 @@ -4487,7 +4489,7 @@ snapshots: kind-of: 6.0.3 object.pick: 1.3.0 regex-not: 1.0.2 - snapdragon: 0.8.2 + snapdragon: 0.8.2(supports-color@10.2.2) to-regex: 3.0.2 transitivePeerDependencies: - supports-color @@ -4867,10 +4869,10 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - snapdragon@0.8.2: + snapdragon@0.8.2(supports-color@10.2.2): dependencies: base: 0.11.2 - debug: 2.6.9 + debug: 2.6.9(supports-color@10.2.2) define-property: 0.2.5 extend-shallow: 2.0.1 map-cache: 0.2.2 @@ -5008,16 +5010,16 @@ snapshots: strip-bom@3.0.0: {} - stylelint-config-recommended@18.0.0(stylelint@17.14.0(typescript@6.0.3)): + stylelint-config-recommended@18.0.0(stylelint@17.14.0(supports-color@10.2.2)(typescript@6.0.3)): dependencies: - stylelint: 17.14.0(typescript@6.0.3) + stylelint: 17.14.0(supports-color@10.2.2)(typescript@6.0.3) - stylelint-config-standard@40.0.0(stylelint@17.14.0(typescript@6.0.3)): + stylelint-config-standard@40.0.0(stylelint@17.14.0(supports-color@10.2.2)(typescript@6.0.3)): dependencies: - stylelint: 17.14.0(typescript@6.0.3) - stylelint-config-recommended: 18.0.0(stylelint@17.14.0(typescript@6.0.3)) + stylelint: 17.14.0(supports-color@10.2.2)(typescript@6.0.3) + stylelint-config-recommended: 18.0.0(stylelint@17.14.0(supports-color@10.2.2)(typescript@6.0.3)) - stylelint@17.14.0(typescript@6.0.3): + stylelint@17.14.0(supports-color@10.2.2)(typescript@6.0.3): dependencies: '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) @@ -5030,7 +5032,7 @@ snapshots: cosmiconfig: 9.0.2(typescript@6.0.3) css-functions-list: 3.3.3 css-tree: 3.2.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) fast-glob: 3.3.3 fastest-levenshtein: 1.0.16 file-entry-cache: 11.1.5 @@ -5156,8 +5158,6 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@4.41.0: {} - type-fest@5.7.0: dependencies: tagged-tag: 1.0.0 @@ -5206,13 +5206,13 @@ snapshots: typed-query-selector@2.12.2: {} - typescript-eslint@8.62.1(eslint@10.6.0)(typescript@6.0.3): + typescript-eslint@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0)(typescript@6.0.3))(eslint@10.6.0)(typescript@6.0.3) - '@typescript-eslint/parser': 8.62.1(eslint@10.6.0)(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.62.1(eslint@10.6.0)(typescript@6.0.3) - eslint: 10.6.0 + '@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.62.1(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.6.0(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 8e78c5a19..5d98126f1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -16,3 +16,5 @@ strictPeerDependencies: false allowBuilds: esbuild: true pmOnFail: warn +minimumReleaseAgeExclude: + - '@vencord/*' From 30ba4da0102a0246bf6686cd0171f35721d7b857 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Mon, 17 Aug 2026 18:17:42 +0200 Subject: [PATCH 2/9] ViewIcons: fix viewing animated images --- src/plugins/viewIcons/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/viewIcons/index.tsx b/src/plugins/viewIcons/index.tsx index 58688e919..c3c830360 100644 --- a/src/plugins/viewIcons/index.tsx +++ b/src/plugins/viewIcons/index.tsx @@ -44,7 +44,7 @@ interface GroupDMContextProps { const settings = definePluginSettings({ format: { type: OptionType.SELECT, - description: "Choose the image format to use for non animated images. Animated images will always use .gif", + description: "Choose the image format to use for non-animated images. Animated images will always use .webp", options: [ { label: "webp", @@ -86,7 +86,7 @@ function openImage({ url, width, height, event }: OpenImageProps) { const format = url.startsWith("/") ? "png" : u.searchParams.get("animated") === "true" - ? "gif" + ? "webp" : settings.store.format; u.searchParams.set("size", settings.store.imgSize); From 79759ffa7e59a7d797626b0abd3bb2b288a727de Mon Sep 17 00:00:00 2001 From: theo Date: Mon, 17 Aug 2026 17:23:54 +0100 Subject: [PATCH 3/9] fix Vencord context menu entries having no icon (#4518) --- packages/discord-types/src/menu.d.ts | 17 +++++++++++++++++ src/plugins/betterRoleContext/index.tsx | 4 ++++ src/plugins/biggerStreamPreview/index.tsx | 1 + src/plugins/copyUserURLs/index.tsx | 1 + .../ui/components/DecorationContextMenu.tsx | 2 ++ src/plugins/newGuildSettings/index.tsx | 1 + .../components/RolesAndUsersPermissions.tsx | 2 ++ src/plugins/reviewDB/index.tsx | 2 ++ src/plugins/spotifyControls/PlayerComponent.tsx | 5 +++++ src/plugins/translate/index.tsx | 1 + src/plugins/unsuppressEmbeds/index.tsx | 1 + src/plugins/viewIcons/index.tsx | 6 ++++++ src/plugins/viewRaw/index.tsx | 2 ++ 13 files changed, 45 insertions(+) diff --git a/packages/discord-types/src/menu.d.ts b/packages/discord-types/src/menu.d.ts index 78810296a..d083dc906 100644 --- a/packages/discord-types/src/menu.d.ts +++ b/packages/discord-types/src/menu.d.ts @@ -2,6 +2,22 @@ import type { ComponentType, CSSProperties, ForwardRefRenderFunction, MouseEvent type RC = ComponentType>>; +type LeadingAccessory = + | { + type: "icon"; + icon: ComponentType; + } + | { + type: "emoji"; + emojiId?: string; + src?: string; + animated?: boolean; + } + | { + type: "image"; + src: string; + }; + export interface Menu { Menu: RC<{ navId: string; @@ -20,6 +36,7 @@ export interface Menu { label: ReactNode; action?(e: MouseEvent): void; icon?: ComponentType; + leadingAccessory?: LeadingAccessory; color?: string; render?: ComponentType; diff --git a/src/plugins/betterRoleContext/index.tsx b/src/plugins/betterRoleContext/index.tsx index 53f603dc3..e45183ff7 100644 --- a/src/plugins/betterRoleContext/index.tsx +++ b/src/plugins/betterRoleContext/index.tsx @@ -90,6 +90,7 @@ export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutR GuildSettingsActions.selectRole(role.id); }} icon={PencilIcon} + leadingAccessory={{ type: "icon", icon: PencilIcon }} /> ), role.colorString && ( @@ -99,6 +100,7 @@ export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutR label="Copy Role Color" action={() => copyToClipboard(role.colorString!)} icon={AppearanceIcon} + leadingAccessory={{ type: "icon", icon: AppearanceIcon }} /> ) ].filter(isTruthy); @@ -117,6 +119,7 @@ export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutR }); }} icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> ), popoutRef && ( @@ -185,6 +188,7 @@ export function openRoleContextMenu(event: React.MouseEvent, { guil id="vc-better-role-context-copy-role-id" label={getIntlMessage("COPY_ID_ROLE")} icon={CopyIdIcon} + leadingAccessory={{ type: "icon", icon: CopyIdIcon }} action={() => copyToClipboard(role.id)} /> diff --git a/src/plugins/biggerStreamPreview/index.tsx b/src/plugins/biggerStreamPreview/index.tsx index a1e8959c9..71b5a9f0e 100644 --- a/src/plugins/biggerStreamPreview/index.tsx +++ b/src/plugins/biggerStreamPreview/index.tsx @@ -70,6 +70,7 @@ export const addViewStreamContext: NavContextMenuPatchCallback = (children, { us label="View Stream Preview" id="view-stream-preview" icon={ScreenshareIcon} + leadingAccessory={{ type: "icon", icon: ScreenshareIcon }} action={() => stream && handleViewPreview(stream)} disabled={!stream} /> diff --git a/src/plugins/copyUserURLs/index.tsx b/src/plugins/copyUserURLs/index.tsx index 07ac0721d..5ca6f990c 100644 --- a/src/plugins/copyUserURLs/index.tsx +++ b/src/plugins/copyUserURLs/index.tsx @@ -39,6 +39,7 @@ const UserContextMenuPatch: NavContextMenuPatchCallback = (children, { user }: U label="Copy User URL" action={() => copyToClipboard(``)} icon={LinkIcon} + leadingAccessory={{ type: "icon", icon: LinkIcon }} /> ); }; diff --git a/src/plugins/decor/ui/components/DecorationContextMenu.tsx b/src/plugins/decor/ui/components/DecorationContextMenu.tsx index a1609bfdf..5addafe49 100644 --- a/src/plugins/decor/ui/components/DecorationContextMenu.tsx +++ b/src/plugins/decor/ui/components/DecorationContextMenu.tsx @@ -23,6 +23,7 @@ export default function DecorationContextMenu({ decoration }: { decoration: Deco id={cl("decoration-context-menu-copy-hash")} label="Copy Decoration Hash" icon={CopyIcon} + leadingAccessory={{ type: "icon", icon: CopyIcon }} action={() => copyToClipboard(decoration.hash)} /> {decoration.authorId === UserStore.getCurrentUser().id && @@ -31,6 +32,7 @@ export default function DecorationContextMenu({ decoration }: { decoration: Deco label="Delete Decoration" color="danger" icon={DeleteIcon} + leadingAccessory={{ type: "icon", icon: DeleteIcon }} action={() => openModal(props => ( NavContextMenuPatchCallb label="Apply NewGuildSettings" id="vc-newguildsettings-apply" icon={shouldAddIcon ? CogWheel : void 0} + leadingAccessory={shouldAddIcon ? { type: "icon", icon: CogWheel } : void 0} action={() => applyDefaultSettings(guild.id)} /> ); diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index 7e573c54d..9279b0dd7 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -230,6 +230,7 @@ function RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: str id={cl("copy-role-id")} label={getIntlMessage("COPY_ID_ROLE")} icon={CopyIdIcon} + leadingAccessory={{ type: "icon", icon: CopyIdIcon }} action={() => copyToClipboard(roleId)} /> @@ -240,6 +241,7 @@ function RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: str id={cl("view-as-role")} label={getIntlMessage("VIEW_AS_ROLE")} icon={ViewAsRoleIcon} + leadingAccessory={{ type: "icon", icon: ViewAsRoleIcon }} action={() => { onClose(); FluxDispatcher.dispatch({ diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx index da3e17e69..59dc13c46 100644 --- a/src/plugins/reviewDB/index.tsx +++ b/src/plugins/reviewDB/index.tsx @@ -50,6 +50,7 @@ const guildPopoutPatch: NavContextMenuPatchCallback = (children, { guild }: { gu label="View Reviews" id="vc-rdb-server-reviews" icon={OpenExternalIcon} + leadingAccessory={{ type: "icon", icon: OpenExternalIcon }} action={() => openReviewsModal(guild.id, guild.name, ReviewType.Server)} /> ); @@ -62,6 +63,7 @@ const userContextPatch: NavContextMenuPatchCallback = (children, { user }: { use label="View Reviews" id="vc-rdb-user-reviews" icon={OpenExternalIcon} + leadingAccessory={{ type: "icon", icon: OpenExternalIcon }} action={() => openReviewsModal(user.id, user.username, ReviewType.User)} /> ); diff --git a/src/plugins/spotifyControls/PlayerComponent.tsx b/src/plugins/spotifyControls/PlayerComponent.tsx index f52ff43ea..ee95eefed 100644 --- a/src/plugins/spotifyControls/PlayerComponent.tsx +++ b/src/plugins/spotifyControls/PlayerComponent.tsx @@ -84,18 +84,21 @@ function CopyContextMenu({ name, type, path }: { type: string; name: string; pat label={`Copy ${type} Name`} action={() => copyWithToast(name)} icon={CopyIcon} + leadingAccessory={{ type: "icon", icon: CopyIcon }} /> copyWithToast("https://open.spotify.com" + path)} icon={LinkIcon} + leadingAccessory={{ type: "icon", icon: LinkIcon }} /> SpotifyStore.openExternal(path)} icon={OpenExternalIcon} + leadingAccessory={{ type: "icon", icon: OpenExternalIcon }} /> ); @@ -225,6 +228,7 @@ function AlbumContextMenu({ track }: { track: Track; }) { label="Open Album" action={() => SpotifyStore.openExternal(`/album/${track.album.id}`)} icon={OpenExternalIcon} + leadingAccessory={{ type: "icon", icon: OpenExternalIcon }} /> openImageModal(track.album.image)} icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> { const trans = await translate("received", content); handleTranslate(message.id, trans); diff --git a/src/plugins/unsuppressEmbeds/index.tsx b/src/plugins/unsuppressEmbeds/index.tsx index 79ddaac70..f0cfb8db6 100644 --- a/src/plugins/unsuppressEmbeds/index.tsx +++ b/src/plugins/unsuppressEmbeds/index.tsx @@ -49,6 +49,7 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = ( label={isEmbedSuppressed ? "Unsuppress Embeds" : "Suppress Embeds"} color={isEmbedSuppressed ? undefined : "danger"} icon={isEmbedSuppressed ? ImageVisible : ImageInvisible} + leadingAccessory={{ type: "icon", icon: isEmbedSuppressed ? ImageVisible : ImageInvisible }} action={() => RestAPI.patch({ url: Constants.Endpoints.MESSAGE(channel.id, messageId), diff --git a/src/plugins/viewIcons/index.tsx b/src/plugins/viewIcons/index.tsx index c3c830360..409eb5a5b 100644 --- a/src/plugins/viewIcons/index.tsx +++ b/src/plugins/viewIcons/index.tsx @@ -117,6 +117,7 @@ const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: U label="View Avatar" action={() => openAvatar(IconUtils.getUserAvatarURL(user, true))} icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> {memberAvatar && ( )} {avatarDecoration && ( @@ -141,6 +143,7 @@ const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: U canAnimate: true })!)} icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> )} @@ -167,6 +170,7 @@ const GuildContext: NavContextMenuPatchCallback = (children, { guild }: GuildCon })!) } icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> ) : null} {banner ? ( @@ -177,6 +181,7 @@ const GuildContext: NavContextMenuPatchCallback = (children, { guild }: GuildCon openBanner(IconUtils.getGuildBannerURL(guild, true)!) } icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> ) : null} @@ -195,6 +200,7 @@ const GroupDMContext: NavContextMenuPatchCallback = (children, { channel }: Grou openAvatar(IconUtils.getChannelIconURL(channel)!) } icon={ImageIcon} + leadingAccessory={{ type: "icon", icon: ImageIcon }} /> )); diff --git a/src/plugins/viewRaw/index.tsx b/src/plugins/viewRaw/index.tsx index 9d3617812..b7c21d0d4 100644 --- a/src/plugins/viewRaw/index.tsx +++ b/src/plugins/viewRaw/index.tsx @@ -151,6 +151,7 @@ function MakeContextCallback(name: "Guild" | "Role" | "User" | "Channel" | "Mess label="View Raw" action={action} icon={CopyRawIcon} + leadingAccessory={{ type: "icon", icon: CopyRawIcon }} /> ); }; @@ -169,6 +170,7 @@ const devContextCallback: NavContextMenuPatchCallback = (children, { id }: { id: label="View Raw" action={() => openViewRawModal(JSON.stringify(role, null, 4), "Role")} icon={CopyRawIcon} + leadingAccessory={{ type: "icon", icon: CopyRawIcon }} /> ); }; From de489fc6bd9a023e7becfaf488b0e3eebe635db6 Mon Sep 17 00:00:00 2001 From: thororen <78185467+thororen1234@users.noreply.github.com> Date: Mon, 17 Aug 2026 12:47:57 -0400 Subject: [PATCH 4/9] ReviewDB: Fix Collection Sorting (#4516) --- src/plugins/reviewDB/components/ReviewsView.tsx | 4 ++-- src/plugins/reviewDB/index.tsx | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx index bd9a94826..8dd83e7e6 100644 --- a/src/plugins/reviewDB/components/ReviewsView.tsx +++ b/src/plugins/reviewDB/components/ReviewsView.tsx @@ -61,7 +61,7 @@ export default function ReviewsView({ }: Props) { const [signal, refetch] = useForceUpdater(true); - const [reviewData] = useAwaiter(() => getReviews(discordId, { offset: (page - 1) * REVIEWS_PER_PAGE, fetchVotes: true }), { + const [reviewData] = useAwaiter(() => getReviews(discordId, { offset: (page - 1) * REVIEWS_PER_PAGE, limit: REVIEWS_PER_PAGE, fetchVotes: true }), { fallbackValue: null, deps: [refetchSignal, signal, page], onSuccess: data => { @@ -69,7 +69,7 @@ export default function ReviewsView({ const systemReviews = data!.reviews.filter(r => r.type === ReviewType.System); const normalReviews = data!.reviews.filter(r => r.type !== ReviewType.System); - data!.reviews = [...systemReviews, ...normalReviews.reverse()]; + data!.reviews = [...systemReviews, ...normalReviews]; scrollToTop?.(); onFetchReviews(data!); } diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx index 59dc13c46..0afdd3e65 100644 --- a/src/plugins/reviewDB/index.tsx +++ b/src/plugins/reviewDB/index.tsx @@ -187,7 +187,6 @@ export default definePlugin({ {reviewData.reviews .filter(review => review.id !== 0) .slice(0, 4) - .reverse() .map((review, idx) => { const showCount = idx === 3 && reviewData.reviewCount > 4; From 32b463059bd2d58509b34a19ce1eeed680051d62 Mon Sep 17 00:00:00 2001 From: theo Date: Mon, 17 Aug 2026 21:20:25 +0100 Subject: [PATCH 5/9] UserVoiceShow: fix visual issues (#4457) --- src/plugins/userVoiceShow/components.tsx | 5 +++-- src/plugins/userVoiceShow/index.tsx | 6 +++--- src/plugins/userVoiceShow/style.css | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/userVoiceShow/components.tsx b/src/plugins/userVoiceShow/components.tsx index 71c7e9b08..3da84a7af 100644 --- a/src/plugins/userVoiceShow/components.tsx +++ b/src/plugins/userVoiceShow/components.tsx @@ -116,13 +116,14 @@ function VoiceChannelTooltip({ channel, isLocked }: VoiceChannelTooltipProps) { export interface VoiceChannelIndicatorProps { userId: string; isProfile?: boolean; + isMessage?: boolean; isActionButton?: boolean; shouldHighlight?: boolean; } const clickTimers = new Map(); -export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId, isProfile, isActionButton, shouldHighlight }: VoiceChannelIndicatorProps) => { +export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId, isProfile, isMessage, isActionButton, shouldHighlight }: VoiceChannelIndicatorProps) => { const channelId = useStateFromStores([VoiceStateStore], () => VoiceStateStore.getVoiceStateForUser(userId)?.channelId); const { isMuted, isDeaf } = useStateFromStores([VoiceStateStore], () => { @@ -192,7 +193,7 @@ export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId, isProfile, is isActionButton && shouldHighlight && ActionButtonClasses.highlight, cl(isProfile && "profile-speaker") )} - size={isActionButton ? 20 : 16} + size={(isActionButton || isMessage) ? 20 : 16} /> )} diff --git a/src/plugins/userVoiceShow/index.tsx b/src/plugins/userVoiceShow/index.tsx index 2d05c2588..81f81ff49 100644 --- a/src/plugins/userVoiceShow/index.tsx +++ b/src/plugins/userVoiceShow/index.tsx @@ -60,8 +60,8 @@ export default definePlugin({ { find: "#{intl::USER_PROFILE_PRONOUNS}", replacement: { - match: /(?<=children:\[\i," ",\i)(?=\])/, - replace: ",$self.VoiceChannelIndicator({userId:arguments[0]?.user?.id,isProfile:true})" + match: /(user:(\i).{0,100}onClickDisplayName:\i,trailing:)(\i)/, + replace: "$1[$self.VoiceChannelIndicator({userId:$2.id,isProfile:true}),$3]" }, predicate: () => settings.store.showInUserProfileModal }, @@ -100,7 +100,7 @@ export default definePlugin({ addMemberListDecorator("UserVoiceShow", ({ user }) => user == null ? null : ); } if (settings.store.showInMessages) { - addMessageDecoration("UserVoiceShow", ({ message }) => message?.author == null ? null : ); + addMessageDecoration("UserVoiceShow", ({ message }) => message?.author == null ? null : ); } }, diff --git a/src/plugins/userVoiceShow/style.css b/src/plugins/userVoiceShow/style.css index 6ee5fd7a0..855d0c4c5 100644 --- a/src/plugins/userVoiceShow/style.css +++ b/src/plugins/userVoiceShow/style.css @@ -14,8 +14,9 @@ } .vc-uvs-profile-speaker { - width: var(--custom-nickname-icon-size); height: var(--custom-nickname-icon-size); + margin-right: 4px; + transform: translateY(1.3px); } .vc-uvs-tooltip-container { From ef29bbeb6119cfb53d1273ed78147bcc97d91261 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Mon, 17 Aug 2026 23:27:25 +0200 Subject: [PATCH 6/9] WebPWA: fix titlebar being hidden outside of PWA --- src/plugins/webPWA.browser/styles.css | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/plugins/webPWA.browser/styles.css b/src/plugins/webPWA.browser/styles.css index ae0137363..25cf2a4ce 100644 --- a/src/plugins/webPWA.browser/styles.css +++ b/src/plugins/webPWA.browser/styles.css @@ -1,21 +1,23 @@ :root { - /* opt out of auto-dark-mode plugins, which break discord css, such as force-dark, dark-reader etc */ - color-scheme: only light; - - /* force title bar to be same as WCO bar height, regardless of zoom, device pixel ratio or OS */ - - /* is only set when WCO is defined, otherwise sets to 0 */ - --custom-app-top-bar-height: env(titlebar-area-height, 0px) !important; + /* opt out of auto-dark-mode plugins, which break discord css, such as force-dark, dark-reader etc */ + color-scheme: only light; } -/* position trailing titlebar elements alongside WCO */ -[class*="bar_"] [class*="trailing_"] { - padding-right: calc(100vw - env(titlebar-area-width, 100%) - env(titlebar-area-x, 0px)); +@media all and not (display-mode: browser) { + :root { + /* force title bar to be same as WCO bar height, regardless of zoom, device pixel ratio or OS, is only set when WCO is defined, otherwise sets to 0 */ + --custom-app-top-bar-height: env(titlebar-area-height, 0px) !important; + } + + /* position trailing titlebar elements alongside WCO */ + [class*="bar_"] [class*="trailing_"] { + padding-right: calc(100vw - env(titlebar-area-width, 100%) - env(titlebar-area-x, 0px)); + } } /* force hide trailing icons when standalone so there's no ugly pixel overflow */ @media all and (display-mode: standalone) { - [class*="bar_"] [class*="trailing_"] { - display: none; - } + [class*="bar_"] [class*="trailing_"] { + display: none; + } } \ No newline at end of file From 3e03b47b45586ca04d302a0ff647c6d05dc8642e Mon Sep 17 00:00:00 2001 From: Vendicated Date: Tue, 18 Aug 2026 01:37:09 +0200 Subject: [PATCH 7/9] add context menu icons to various plugins --- packages/discord-types/src/menu.d.ts | 7 ++- src/components/Icons.tsx | 45 +++++++++++++++++++ src/plugins/_api/badges/index.tsx | 3 ++ src/plugins/betterRoleContext/index.tsx | 1 + src/plugins/copyEmojiMarkdown/index.tsx | 2 + src/plugins/copyStickerLinks/index.tsx | 8 +++- src/plugins/expressionCloner/index.tsx | 2 + src/plugins/messageLogger/index.tsx | 3 ++ .../components/RolesAndUsersPermissions.tsx | 1 + src/plugins/permissionsViewer/index.tsx | 15 ++++--- src/plugins/previewMessage/index.tsx | 10 ++--- src/plugins/replaceGoogleSearch/index.tsx | 19 ++------ src/plugins/reverseImageSearch/index.tsx | 28 +++--------- src/plugins/serverInfo/index.tsx | 8 ++-- 14 files changed, 94 insertions(+), 58 deletions(-) diff --git a/packages/discord-types/src/menu.d.ts b/packages/discord-types/src/menu.d.ts index d083dc906..9235d31c6 100644 --- a/packages/discord-types/src/menu.d.ts +++ b/packages/discord-types/src/menu.d.ts @@ -1,11 +1,14 @@ import type { ComponentType, CSSProperties, ForwardRefRenderFunction, MouseEvent, PropsWithChildren, ReactNode, UIEvent } from "react"; +import { LiteralUnion } from "type-fest"; type RC = ComponentType>>; -type LeadingAccessory = +type Accessory = | { type: "icon"; icon: ComponentType; + color?: string; + size?: LiteralUnion<"refresh_sm", string>; } | { type: "emoji"; @@ -36,7 +39,7 @@ export interface Menu { label: ReactNode; action?(e: MouseEvent): void; icon?: ComponentType; - leadingAccessory?: LeadingAccessory; + leadingAccessory?: Accessory; color?: string; render?: ComponentType; diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index ff89b3f48..008a7a893 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -640,6 +640,20 @@ export function RightArrow(props: IconProps) { ); } +export function TopRightArrow(props: IconProps) { + return ( + + + + ); +} + export function StarFilled(props: IconProps) { return ( ); } + +export function SearchIcon(props: IconProps) { + return ( + + + + ); +} + +export function EyeIcon(props: IconProps) { + return ( + + + + ); +} diff --git a/src/plugins/_api/badges/index.tsx b/src/plugins/_api/badges/index.tsx index 2bdefa97b..d91b4eae7 100644 --- a/src/plugins/_api/badges/index.tsx +++ b/src/plugins/_api/badges/index.tsx @@ -22,6 +22,7 @@ import { _getBadges, BadgePosition, BadgeUserArgs, ProfileBadge } from "@api/Bad import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { Heart } from "@components/Heart"; +import { CopyIcon, LinkIcon } from "@components/Icons"; import DonateButton from "@components/settings/DonateButton"; import { openContributorModal } from "@components/settings/tabs"; import { Devs } from "@utils/constants"; @@ -68,6 +69,7 @@ function BadgeContextMenu({ badge }: { badge: Omit & BadgeUs id="vc-badge-copy-name" label="Copy Badge Name" action={() => copyWithToast(badge.description!)} + leadingAccessory={{ type: "icon", icon: CopyIcon }} /> )} {badge.iconSrc && ( @@ -75,6 +77,7 @@ function BadgeContextMenu({ badge }: { badge: Omit & BadgeUs id="vc-badge-copy-link" label="Copy Badge Image Link" action={() => copyWithToast(badge.iconSrc!)} + leadingAccessory={{ type: "icon", icon: LinkIcon }} /> )} diff --git a/src/plugins/betterRoleContext/index.tsx b/src/plugins/betterRoleContext/index.tsx index e45183ff7..9b5653aef 100644 --- a/src/plugins/betterRoleContext/index.tsx +++ b/src/plugins/betterRoleContext/index.tsx @@ -150,6 +150,7 @@ export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutR {...popoutProps} >
View Role Members
+ {/* FIXME: update to new icon style */}
diff --git a/src/plugins/copyEmojiMarkdown/index.tsx b/src/plugins/copyEmojiMarkdown/index.tsx index dfa46a350..8b8fd38db 100644 --- a/src/plugins/copyEmojiMarkdown/index.tsx +++ b/src/plugins/copyEmojiMarkdown/index.tsx @@ -5,6 +5,7 @@ */ import { definePluginSettings } from "@api/Settings"; +import { CopyIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import { copyWithToast } from "@utils/discord"; import definePlugin, { OptionType } from "@utils/types"; @@ -69,6 +70,7 @@ export default definePlugin({ "Success! Copied emoji markdown." ); }} + leadingAccessory={{ type: "icon", icon: CopyIcon }} /> ); }, diff --git a/src/plugins/copyStickerLinks/index.tsx b/src/plugins/copyStickerLinks/index.tsx index 530f19509..2e3d3ed69 100644 --- a/src/plugins/copyStickerLinks/index.tsx +++ b/src/plugins/copyStickerLinks/index.tsx @@ -18,6 +18,7 @@ import { NavContextMenuPatchCallback } from "@api/ContextMenu"; import { isPluginEnabled } from "@api/PluginManager"; +import { LinkIcon, TopRightArrow } from "@components/Icons"; import ExpressionClonerPlugin from "@plugins/expressionCloner"; import { Devs } from "@utils/constants"; import { copyWithToast } from "@utils/discord"; @@ -43,14 +44,17 @@ function buildMenuItem(sticker: PartialSticker, addBottomSeparator: boolean) { copyWithToast(getUrl(sticker), "Link copied!")} /> VencordNative.native.openExternal(getUrl(sticker))} /> diff --git a/src/plugins/expressionCloner/index.tsx b/src/plugins/expressionCloner/index.tsx index 9f99cc15e..57bde0457 100644 --- a/src/plugins/expressionCloner/index.tsx +++ b/src/plugins/expressionCloner/index.tsx @@ -21,6 +21,7 @@ import { migratePluginSettings } from "@api/Settings"; import { BaseText } from "@components/BaseText"; import { CheckedTextInput } from "@components/CheckedTextInput"; import { Flex } from "@components/Flex"; +import { PlusIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import { getGuildAcronym, hasGuildFeature } from "@utils/discord"; import { Logger } from "@utils/Logger"; @@ -327,6 +328,7 @@ function buildMenuItem(type: "Emoji" | "Sticker", fetchData: () => Promisable openModalLazy(async () => { const res = await fetchData(); diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx index 130f0c9b5..b598b7e5e 100644 --- a/src/plugins/messageLogger/index.tsx +++ b/src/plugins/messageLogger/index.tsx @@ -23,6 +23,7 @@ import { updateMessage } from "@api/MessageUpdater"; import { definePluginSettings } from "@api/Settings"; import { disableStyle, enableStyle } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; +import { DeleteIcon, EyeIcon } from "@components/Icons"; import { Devs, SUPPORT_CATEGORY_ID, VENBOT_USER_ID } from "@utils/constants"; import { getIntlMessage } from "@utils/discord"; import { Logger } from "@utils/Logger"; @@ -176,6 +177,7 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = id={TOGGLE_DELETE_STYLE_ID} key={TOGGLE_DELETE_STYLE_ID} label="Toggle Deleted Highlight" + leadingAccessory={{ type: "icon", icon: EyeIcon }} action={() => domElement.classList.toggle("messagelogger-deleted")} /> )); @@ -186,6 +188,7 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = id={REMOVE_HISTORY_ID} key={REMOVE_HISTORY_ID} label="Remove Message History" + leadingAccessory={{ type: "icon", icon: DeleteIcon }} color="danger" action={() => { clearMessageHistory(message); diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index 9279b0dd7..45897547a 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -271,6 +271,7 @@ function UserContextMenu({ userId }: { userId: string; }) { { copyToClipboard(userId); }} diff --git a/src/plugins/permissionsViewer/index.tsx b/src/plugins/permissionsViewer/index.tsx index b8b011b73..54d9135fd 100644 --- a/src/plugins/permissionsViewer/index.tsx +++ b/src/plugins/permissionsViewer/index.tsx @@ -59,13 +59,14 @@ export const settings = definePluginSettings({ }, }); -function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { +function MenuItem(guildId: string, { id, type, withIcon }: { id?: string, type?: MenuItemParentType, withIcon?: boolean; }) { if (type === MenuItemParentType.User && !GuildMemberStore.isMember(guildId, id!)) return null; return ( { const guild = GuildStore.getGuild(guildId); @@ -125,7 +126,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { ); } -function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentType): NavContextMenuPatchCallback { +function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentType, withIcon = false): NavContextMenuPatchCallback { return (children, props) => { if ( !props || @@ -139,9 +140,9 @@ function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentT const group = findGroupChildrenByChildId(childId, children); const item = match(type) - .with(MenuItemParentType.User, () => MenuItem(props.guildId, props.user.id, type)) - .with(MenuItemParentType.Channel, () => MenuItem(props.guild.id, props.channel.id, type)) - .with(MenuItemParentType.Guild, () => MenuItem(props.guild.id)) + .with(MenuItemParentType.User, () => MenuItem(props.guildId, { id: props.user.id, type, withIcon })) + .with(MenuItemParentType.Channel, () => MenuItem(props.guild.id, { id: props.channel.id, type, withIcon })) + .with(MenuItemParentType.Guild, () => MenuItem(props.guild.id, { withIcon })) .otherwise(() => null); if (item == null) return; @@ -214,6 +215,6 @@ export default definePlugin({ "user-context": makeContextMenuPatch("roles", MenuItemParentType.User), "channel-context": makeContextMenuPatch(["mute-channel", "unmute-channel"], MenuItemParentType.Channel), "guild-context": makeContextMenuPatch("privacy", MenuItemParentType.Guild), - "guild-header-popout": makeContextMenuPatch("privacy", MenuItemParentType.Guild) + "guild-header-popout": makeContextMenuPatch("privacy", MenuItemParentType.Guild, true) } }); diff --git a/src/plugins/previewMessage/index.tsx b/src/plugins/previewMessage/index.tsx index 4d2aa89c3..285376ad4 100644 --- a/src/plugins/previewMessage/index.tsx +++ b/src/plugins/previewMessage/index.tsx @@ -18,6 +18,7 @@ import { ChatBarButton, ChatBarButtonFactory } from "@api/ChatButtons"; import { generateId, sendBotMessage } from "@api/Commands"; +import { EyeIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin, { IconComponent, StartAt } from "@utils/types"; import { CloudUpload, MessageAttachment } from "@vencord/discord-types"; @@ -75,17 +76,12 @@ const getAttachments = async (channelId: string) => const PreviewIcon: IconComponent = ({ height = 20, width = 20, className }) => { return ( - - - + /> ); }; diff --git a/src/plugins/replaceGoogleSearch/index.tsx b/src/plugins/replaceGoogleSearch/index.tsx index 223a2dd0f..96d11f87d 100644 --- a/src/plugins/replaceGoogleSearch/index.tsx +++ b/src/plugins/replaceGoogleSearch/index.tsx @@ -6,7 +6,7 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; import { definePluginSettings } from "@api/Settings"; -import { Flex } from "@components/Flex"; +import { SearchIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { Menu } from "@webpack/common"; @@ -89,6 +89,7 @@ function makeSearchItem(src: string) { label="Search Text" key="search-text" id="vc-search-text" + leadingAccessory={{ type: "icon", icon: SearchIcon }} > {Object.keys(Engines).map(engine => { const key = "vc-search-content-" + engine; @@ -96,20 +97,8 @@ function makeSearchItem(src: string) { - - {engine} - - } + label={engine} + leadingAccessory={{ type: "image", src: `https://icons.duckduckgo.com/ip3/${new URL(Engines[engine]).hostname}.ico` }} action={() => search(src, Engines[engine])} /> ); diff --git a/src/plugins/reverseImageSearch/index.tsx b/src/plugins/reverseImageSearch/index.tsx index 68845c0a1..1ecdf864d 100644 --- a/src/plugins/reverseImageSearch/index.tsx +++ b/src/plugins/reverseImageSearch/index.tsx @@ -17,8 +17,7 @@ */ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; -import { Flex } from "@components/Flex"; -import { OpenExternalIcon } from "@components/Icons"; +import { OpenExternalIcon, SearchIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { Menu } from "@webpack/common"; @@ -43,6 +42,7 @@ function makeSearchItem(src: string) { label="Search Image" key="search-image" id="search-image" + leadingAccessory={{ type: "icon", icon: SearchIcon }} > {Object.keys(Engines).map((engine, i) => { const key = "search-image-" + engine; @@ -50,20 +50,8 @@ function makeSearchItem(src: string) { - - {engine} - - } + label={engine} + leadingAccessory={{ type: "image", src: `https://icons.duckduckgo.com/ip3/${new URL(Engines[engine]).host}.ico` }} action={() => search(src, Engines[engine])} /> ); @@ -71,12 +59,8 @@ function makeSearchItem(src: string) { - - All - - } + label="All" + leadingAccessory={{ type: "icon", icon: OpenExternalIcon }} action={() => Object.values(Engines).forEach(e => search(src, e))} /> diff --git a/src/plugins/serverInfo/index.tsx b/src/plugins/serverInfo/index.tsx index 5a6f51c31..5afdaf7c3 100644 --- a/src/plugins/serverInfo/index.tsx +++ b/src/plugins/serverInfo/index.tsx @@ -5,6 +5,7 @@ */ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { InfoIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { Guild } from "@vencord/discord-types"; @@ -12,13 +13,14 @@ import { Menu } from "@webpack/common"; import { openGuildInfoModal } from "./GuildInfoModal"; -const Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild; }) => { +const makePatch: (showIcon: boolean) => NavContextMenuPatchCallback = showIcon => (children, { guild }: { guild: Guild; }) => { const group = findGroupChildrenByChildId("privacy", children); group?.push( openGuildInfoModal(guild)} /> ); @@ -33,7 +35,7 @@ export default definePlugin({ searchTerms: ["guild", "info", "ServerProfile"], contextMenus: { - "guild-context": Patch, - "guild-header-popout": Patch + "guild-context": makePatch(false), + "guild-header-popout": makePatch(true) } }); From d3de91e4213d2b84d6e34ba7df26630127e1ac87 Mon Sep 17 00:00:00 2001 From: sadan <117494111+sadan4@users.noreply.github.com> Date: Mon, 17 Aug 2026 19:41:40 -0400 Subject: [PATCH 8/9] LoadLazyChunks: Clean up and performance improvements (#4509) Co-authored-by: V Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> --- src/debug/loadLazyChunks.ts | 92 +++++++++++++++++++++---------------- src/debug/runReporter.ts | 7 ++- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/debug/loadLazyChunks.ts b/src/debug/loadLazyChunks.ts index c3d328044..4a71c8f6e 100644 --- a/src/debug/loadLazyChunks.ts +++ b/src/debug/loadLazyChunks.ts @@ -14,7 +14,7 @@ import pLimit from "p-limit"; function getWebpackChunkMap() { const sym = Symbol(); - let chunksMap: unknown; + let chunksMap: unknown = null; Object.defineProperty(Object.prototype, sym, { get() { @@ -30,9 +30,38 @@ function getWebpackChunkMap() { return chunksMap as Record | null; } +let chunksAlreadyLoaded = false; + export async function loadLazyChunks() { const LazyChunkLoaderLogger = new Logger("LazyChunkLoader"); + + if (chunksAlreadyLoaded) { + LazyChunkLoaderLogger.log("Lazy chunks have already been loaded"); + return; + } + const queue = pLimit(50); + const workerAssetCache = new Map>(); + const WORKER_ASSET_REGEX = /importScripts\(|self\.postMessage/; + + async function isWorkerAsset(url: string, useQueue: boolean = true): Promise { + if (workerAssetCache.has(url)) { + return workerAssetCache.get(url)!; + } + + const doFetch = () => { + return fetch(url) + .then(r => r.text()) + .then(t => WORKER_ASSET_REGEX.test(t)); + }; + + const res = useQueue + ? queue(doFetch) + : doFetch(); + + workerAssetCache.set(url, res); + return res; + } try { LazyChunkLoaderLogger.log("Loading all chunks..."); @@ -41,12 +70,12 @@ export async function loadLazyChunks() { const invalidChunks = new Set(); const deferredRequires = new Set(); - const { promise: chunksSearchingDone, resolve: chunksSearchingResolve } = Promise.withResolvers(); + const { promise: chunkSearchingDone, resolve: chunkSearchingDoneResolve } = Promise.withResolvers(); - // True if resolved, false otherwise - const chunksSearchPromises = [] as Array<() => boolean>; + // True if searching promise for that chunk is resolved, false otherwise + let chunkSearchResolvedGetters = [] as Array<() => boolean>; - // This regex loads all language packs which makes webpack finds testing extremely slow, so for now, we prioritize using the one which doesnt include those + // This regex loads all language packs which makes webpack finds testing extremely slow, so for now, we prioritize using the one which doesn't include those const CompleteLazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?((?:\i\.e\("?[^)]+?"?\),?)+?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g); const PartialLazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?((?:\i\.e\("?[^)]+?"?\),?)+?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g); @@ -56,7 +85,7 @@ export async function loadLazyChunks() { // Workaround to avoid loading the CSS debugging chunk which turns the app pink // const hasCssDebuggingLoad = foundCssDebuggingLoad ? false : (foundCssDebuggingLoad = factoryCode.includes(".cssDebuggingEnabled&&")); - // Disabled for now since this causes lots of chunks concatenated into the same module get marked as invalid, and thus not loaded. + // Disabled for now since this causes lots of chunks concatenated into the same module to get marked as invalid, and thus not loaded. const hasCssDebuggingLoad = foundCssDebuggingLoad = false; const lazyChunks = factoryCode.matchAll(hasCssDebuggingLoad ? CompleteLazyChunkRegex : PartialLazyChunkRegex); @@ -93,13 +122,7 @@ export async function loadLazyChunks() { if (wreq.u(id) == null || wreq.u(id) === "undefined.js") continue; - const isWorkerAsset = await queue(() => - fetch(wreq.p + wreq.u(id)) - .then(r => r.text()) - .then(t => /importScripts\(|self\.postMessage/.test(t)) - ); - - if (isWorkerAsset) { + if (await isWorkerAsset(wreq.p + wreq.u(id))) { invalidChunks.add(id); invalidChunkGroup = true; continue; @@ -140,35 +163,27 @@ export async function loadLazyChunks() { } } - // setImmediate to only check if all chunks were loaded after this function resolves - // We check if all chunks were loaded every time a factory is loaded - // If we are still looking for chunks in the other factories, the array will have that factory's chunk search promise not resolved - // But, if all chunk search promises are resolved, this means we found every lazy chunk loaded by Discord code and manually loaded them + + // Filter out resolved chunk search promises. If the array length is 0 that means all the pending searches and loadings are done + // and our regex has finished scanning all modules. Once this happens, the artificial "natural" loading of chunks has been completed + // and we can continue with the rest of the code. + // setImmediate here is needed so the filtering also includes the promises created from searching the modules loaded by the current invokation. + // Otherwise, it could resolve before the async code being put at the end of the event loop has a chance to run and add the promise to the array. + // The async code mentioned is the invokation of the current function from the factoryListener. setTimeout(() => { - let allResolved = true; - - for (let i = 0; i < chunksSearchPromises.length; i++) { - const isResolved = chunksSearchPromises[i](); - - if (isResolved) { - // Remove finished promises to avoid having to iterate through a huge array everytime - chunksSearchPromises.splice(i--, 1); - } else { - allResolved = false; - } + chunkSearchResolvedGetters = chunkSearchResolvedGetters.filter(isResolvedGetter => !isResolvedGetter()); + if (chunkSearchResolvedGetters.length === 0) { + chunkSearchingDoneResolve(); } - - if (allResolved) chunksSearchingResolve(); }, 0); } function factoryListener(factory: AnyModuleFactory | ModuleFactory) { let isResolved = false; searchAndLoadLazyChunks(String(factory)) - .then(() => isResolved = true) - .catch(() => isResolved = true); + .finally(() => isResolved = true); - chunksSearchPromises.push(() => isResolved); + chunkSearchResolvedGetters.push(() => isResolved); } Webpack.factoryListeners.add(factoryListener); @@ -176,7 +191,7 @@ export async function loadLazyChunks() { factoryListener(wreq.m[moduleId]); } - await chunksSearchingDone; + await chunkSearchingDone; Webpack.factoryListeners.delete(factoryListener); // Require deferred entry points @@ -198,17 +213,16 @@ export async function loadLazyChunks() { }); await Promise.all(chunksLeft.map(async id => queue(async () => { - const isWorkerAsset = await fetch(wreq.p + wreq.u(id)) - .then(r => r.text()) - .then(t => /importScripts\(|self\.postMessage/.test(t)); + // We will deadlock if we use the queue inside a queue func + const isWorkerFile = await isWorkerAsset(wreq.p + wreq.u(id), false); - // Loads the chunk. Currently this only happens with the language packs which are loaded differently - if (!isWorkerAsset) { + if (!isWorkerFile) { await wreq.e(id); } }))); LazyChunkLoaderLogger.log("Finished loading all chunks!"); + chunksAlreadyLoaded = true; } catch (e) { LazyChunkLoaderLogger.log("A fatal error occurred:", e); } diff --git a/src/debug/runReporter.ts b/src/debug/runReporter.ts index 2be235dfa..982113aac 100644 --- a/src/debug/runReporter.ts +++ b/src/debug/runReporter.ts @@ -17,7 +17,7 @@ async function runReporter() { try { ReporterLogger.log("Starting test..."); - const { promise: loadLazyChunksDone, resolve: loadLazyChunksResolve } = Promise.withResolvers(); + const { promise: loadLazyChunksDone, resolve: loadLazyChunksDoneResolve } = Promise.withResolvers(); // The main patch for starting the reporter chunk loading addPatch({ @@ -28,11 +28,10 @@ async function runReporter() { } }, "Vencord Reporter"); + // initReporter is called in the patched entry point of Discord // @ts-expect-error Vencord.Webpack._initReporter = function () { - // initReporter is called in the patched entry point of Discord - // setImmediate to only start searching for lazy chunks after Discord initialized the app - setTimeout(() => loadLazyChunks().then(loadLazyChunksResolve), 0); + loadLazyChunks().then(loadLazyChunksDoneResolve); }; await loadLazyChunksDone; From 305eac5d269c58fd10cc7ffa86620ef0886bcea9 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Tue, 18 Aug 2026 02:08:43 +0200 Subject: [PATCH 9/9] Improve settings UI --- src/Vencord.ts | 3 +- src/components/FormSwitch.css | 4 +++ src/components/FormSwitch.tsx | 2 +- .../settings/tabs/plugins/UIElements.css | 4 +++ .../settings/tabs/plugins/UIElements.tsx | 4 +-- .../tabs/plugins/components/styles.css | 2 +- src/components/settings/tabs/styles.css | 5 ++++ .../settings/tabs/updater/index.tsx | 30 +++++++++++-------- .../settings/tabs/vencord/index.tsx | 18 +++++++---- 9 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/Vencord.ts b/src/Vencord.ts index 430d61ed0..17790136d 100644 --- a/src/Vencord.ts +++ b/src/Vencord.ts @@ -63,7 +63,8 @@ async function syncSettings() { body: "We've noticed you have cloud integrations enabled in another client! Due to limitations, you will " + "need to re-authenticate to continue using them. Click here to go to the settings page to do so!", color: "var(--yellow-360)", - onClick: () => SettingsRouter.openUserSettings("vencord_cloud_panel") + onClick: () => SettingsRouter.openUserSettings("vencord_cloud_panel"), + noPersist: true }); return; } diff --git a/src/components/FormSwitch.css b/src/components/FormSwitch.css index 129c58475..44575d985 100644 --- a/src/components/FormSwitch.css +++ b/src/components/FormSwitch.css @@ -27,4 +27,8 @@ .vc-form-switch-border { margin-top: 20px; +} + +.vc-form-switch-description { + color: var(--text-subtle); } \ No newline at end of file diff --git a/src/components/FormSwitch.tsx b/src/components/FormSwitch.tsx index 255f77992..ed436c3d4 100644 --- a/src/components/FormSwitch.tsx +++ b/src/components/FormSwitch.tsx @@ -30,7 +30,7 @@ export function FormSwitch({ onChange, title, value, description, disabled, clas
{title} - {description && {description}} + {description && {description}}
diff --git a/src/components/settings/tabs/plugins/UIElements.css b/src/components/settings/tabs/plugins/UIElements.css index a362aad6a..3c3ba6b27 100644 --- a/src/components/settings/tabs/plugins/UIElements.css +++ b/src/components/settings/tabs/plugins/UIElements.css @@ -38,4 +38,8 @@ :last-child { margin-left: auto; } +} + +.vc-plugin-ui-elements-description { + color: var(--text-subtle); } \ No newline at end of file diff --git a/src/components/settings/tabs/plugins/UIElements.tsx b/src/components/settings/tabs/plugins/UIElements.tsx index ba33fe43d..be5293d49 100644 --- a/src/components/settings/tabs/plugins/UIElements.tsx +++ b/src/components/settings/tabs/plugins/UIElements.tsx @@ -19,7 +19,7 @@ import { Margins } from "@utils/margins"; import { classes } from "@utils/misc"; import { IconComponent } from "@utils/types"; import { RenderModalProps } from "@vencord/discord-types"; -import { Clickable, Modal,openModal } from "@webpack/common"; +import { Clickable, Modal, openModal } from "@webpack/common"; const cl = classNameFactory("vc-plugin-ui-elements-"); @@ -76,7 +76,7 @@ function Section(props: { return (
{title} - {description} + {description}
{switches.length === 0 && ( diff --git a/src/components/settings/tabs/plugins/components/styles.css b/src/components/settings/tabs/plugins/components/styles.css index f104d4db5..52da69841 100644 --- a/src/components/settings/tabs/plugins/components/styles.css +++ b/src/components/settings/tabs/plugins/components/styles.css @@ -27,7 +27,7 @@ } .vc-plugins-setting-description { - color: var(--text-default); + color: var(--text-subtle); } .vc-plugins-setting-error { diff --git a/src/components/settings/tabs/styles.css b/src/components/settings/tabs/styles.css index 6985a6ff7..89b9014a0 100644 --- a/src/components/settings/tabs/styles.css +++ b/src/components/settings/tabs/styles.css @@ -59,4 +59,9 @@ .vc-cloud-button-icon { height: 1.25em; +} + +.vc-settings-switches { + display: grid; + gap: 8px; } \ No newline at end of file diff --git a/src/components/settings/tabs/updater/index.tsx b/src/components/settings/tabs/updater/index.tsx index 30191cb91..52960c60e 100644 --- a/src/components/settings/tabs/updater/index.tsx +++ b/src/components/settings/tabs/updater/index.tsx @@ -81,19 +81,23 @@ function Updater() { - settings.autoUpdate = v} - /> - settings.autoUpdateNotification = v} - disabled={!settings.autoUpdate} - /> +
+ settings.autoUpdate = v} + hideBorder + /> + settings.autoUpdateNotification = v} + disabled={!settings.autoUpdate} + hideBorder + /> +
Repo diff --git a/src/components/settings/tabs/vencord/index.tsx b/src/components/settings/tabs/vencord/index.tsx index ce06f431b..ca4ddede6 100644 --- a/src/components/settings/tabs/vencord/index.tsx +++ b/src/components/settings/tabs/vencord/index.tsx @@ -57,11 +57,7 @@ function Switches() { { key: "useQuickCss", title: "Enable Custom CSS", - }, - !IS_WEB && { - key: "enableReactDevtools", - title: "Enable React Developer Tools", - restartRequired: true + description: "Apply your configured QuickCSS" }, !IS_WEB && (!IS_DISCORD_DESKTOP || !IS_WINDOWS ? { key: "frameless", @@ -81,6 +77,7 @@ function Switches() { IS_DISCORD_DESKTOP && { key: "disableMinSize", title: "Disable minimum window size", + description: "Allows you to resize the window to any size, even smaller than Discord's minimum size", restartRequired: true }, !IS_WEB && IS_WINDOWS && { @@ -88,6 +85,12 @@ function Switches() { title: "Register Ctrl+Q as shortcut to close Discord (Alternative to Alt+F4)", restartRequired: true }, + !IS_WEB && { + key: "enableReactDevtools", + title: "Enable React Developer Tools", + description: "Mainly useful for plugin developers. Ignore this if you don't know what it is", + restartRequired: true + }, ] satisfies Array; title: string; @@ -108,6 +111,7 @@ function Switches() { title={title} description={description} value={settings[key]} + hideBorder onChange={v => { settings[key] = v; @@ -226,7 +230,9 @@ function VencordSettings() { ! - +
+ +