Merge branch 'dev' into fix/FakeNitro

This commit is contained in:
T14D3 2025-02-19 08:24:05 +01:00 committed by GitHub
commit 8028edd244
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 718 additions and 1204 deletions

View file

@ -5,15 +5,9 @@ body:
- type: markdown
attributes:
value: |
# READ THIS BEFORE OPENING AN ISSUE
![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true)
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer.
- type: textarea
id: content

View file

@ -7,24 +7,9 @@ body:
- type: markdown
attributes:
value: |
# READ THIS BEFORE OPENING AN ISSUE
![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true)
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
- type: input
id: discord
attributes:
label: Discord Account
description: Who on Discord is making this request? Not required but encouraged for easier follow-up
placeholder: username#0000
validations:
required: false
GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer.
- type: textarea
id: bug-description
@ -77,5 +62,5 @@ body:
options:
- label: I am using Discord Stable or tried on Stable and this bug happens there as well
required: true
- label: I have read the requirements for opening an issue above
- label: I am a Vencord Developer
required: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -24,7 +24,7 @@
"dev": "pnpm watch",
"watchWeb": "pnpm buildWeb --watch",
"generatePluginJson": "tsx scripts/generatePluginList.ts",
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types",
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types --allowJs false",
"inject": "node scripts/runInstaller.mjs",
"uninject": "node scripts/runInstaller.mjs",
"lint": "eslint",
@ -45,31 +45,31 @@
"virtual-merge": "^1.0.1"
},
"devDependencies": {
"@stylistic/eslint-plugin": "^2.12.1",
"@types/chrome": "^0.0.287",
"@types/diff": "^6.0.0",
"@stylistic/eslint-plugin": "^4.0.0",
"@types/chrome": "^0.0.304",
"@types/diff": "^7.0.1",
"@types/lodash": "^4.17.14",
"@types/node": "^22.10.5",
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@types/yazl": "^2.4.5",
"diff": "^7.0.0",
"discord-types": "^1.3.26",
"esbuild": "^0.25.0",
"eslint": "^9.17.0",
"eslint": "^9.20.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-path-alias": "2.1.0",
"eslint-plugin-react": "^7.37.3",
"eslint-plugin-simple-header": "^1.2.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unused-imports": "^4.1.4",
"highlight.js": "11.7.0",
"highlight.js": "11.11.1",
"html-minifier-terser": "^7.2.0",
"moment": "^2.22.2",
"puppeteer-core": "^23.11.1",
"standalone-electron-types": "^1.0.0",
"puppeteer-core": "^24.2.1",
"standalone-electron-types": "^34.2.0",
"stylelint": "^16.12.0",
"stylelint-config-standard": "^36.0.1",
"stylelint-config-standard": "^37.0.0",
"ts-patch": "^3.3.0",
"ts-pattern": "^5.6.0",
"tsx": "^4.19.2",
@ -79,10 +79,10 @@
"typescript-transform-paths": "^3.5.3",
"zip-local": "^0.3.5"
},
"packageManager": "pnpm@9.1.0",
"packageManager": "pnpm@10.4.1",
"pnpm": {
"patchedDependencies": {
"eslint@9.17.0": "patches/eslint@9.17.0.patch",
"eslint@9.20.1": "patches/eslint@9.20.1.patch",
"eslint-plugin-path-alias@2.1.0": "patches/eslint-plugin-path-alias@2.1.0.patch"
},
"peerDependencyRules": {
@ -95,18 +95,14 @@
"source-map-resolve": "*",
"resolve-url": "*",
"source-map-url": "*",
"urix": "*"
}
"urix": "*",
"q": "*"
},
"webExt": {
"artifactsDir": "./dist",
"build": {
"overwriteDest": true
},
"sourceDir": "./dist/firefox-unpacked"
"onlyBuiltDependencies": [
"esbuild"
]
},
"engines": {
"node": ">=18",
"pnpm": ">=9"
"node": ">=18"
}
}

View file

@ -1,7 +1,7 @@
{
"name": "@vencord/types",
"private": false,
"version": "0.1.3",
"version": "1.11.5",
"description": "",
"types": "index.d.ts",
"scripts": {
@ -13,16 +13,16 @@
"license": "GPL-3.0",
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"fs-extra": "^11.2.0",
"tsx": "^3.12.6"
"fs-extra": "^11.3.0",
"tsx": "^4.19.2"
},
"dependencies": {
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.18",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.0.10",
"@types/lodash": "4.17.15",
"@types/node": "^22.13.4",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.1",
"discord-types": "^1.3.26",
"standalone-electron-types": "^1.0.0",
"type-fest": "^3.5.3"
"standalone-electron-types": "^34.2.0",
"type-fest": "^4.35.0"
}
}

1592
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -4,11 +4,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import type { Settings } from "@api/Settings";
import { PluginIpcMappings } from "@main/ipcPlugins";
import type { UserThemeHeader } from "@main/themes";
import { IpcEvents } from "@shared/IpcEvents";
import { IpcRes } from "@utils/types";
import type { Settings } from "api/Settings";
import { ipcRenderer } from "electron";
function invoke<T = any>(event: IpcEvents, ...args: any[]) {

View file

@ -68,7 +68,7 @@ export async function loadLazyChunks() {
const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
.then(r => r.text())
.then(t => t.includes("importScripts("));
.then(t => /importScripts\(|self\.postMessage/.test(t));
if (isWorkerAsset) {
invalidChunks.add(id);
@ -174,7 +174,7 @@ export async function loadLazyChunks() {
await Promise.all(chunksLeft.map(async id => {
const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
.then(r => r.text())
.then(t => t.includes("importScripts("));
.then(t => /importScripts\(|self\.postMessage/.test(t));
// Loads the chunk. Currently this only happens with the language packs which are loaded differently
if (!isWorkerAsset) {

View file

@ -5,7 +5,7 @@
*/
import { CopyIcon, DeleteIcon } from "@components/Icons";
import { Alerts, Clipboard, ContextMenuApi, Menu, UserStore } from "webpack/common";
import { Alerts, Clipboard, ContextMenuApi, Menu, UserStore } from "@webpack/common";
import { Decoration } from "../../lib/api";
import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDecorationsStore";

View file

@ -9,7 +9,7 @@ import { app } from "electron";
app.on("browser-window-created", (_, win) => {
win.webContents.on("frame-created", (_, { frame }) => {
frame.once("dom-ready", () => {
frame?.once("dom-ready", () => {
if (frame.url.startsWith("https://open.spotify.com/embed/")) {
const settings = RendererSettings.store.plugins?.FixSpotifyEmbeds;
if (!settings?.enabled) return;

View file

@ -9,7 +9,7 @@ import { app } from "electron";
app.on("browser-window-created", (_, win) => {
win.webContents.on("frame-created", (_, { frame }) => {
frame.once("dom-ready", () => {
frame?.once("dom-ready", () => {
if (frame.url.startsWith("https://www.youtube.com/")) {
const settings = RendererSettings.store.plugins?.FixYoutubeEmbeds;
if (!settings?.enabled) return;

View file

@ -12,7 +12,7 @@ import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
import { Button, Forms, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "webpack/common";
import { Button, Forms, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "@webpack/common";
const enum ActivitiesTypes {
Game,

View file

@ -96,6 +96,6 @@
.vc-shiki-root .vc-shiki-table-cell:last-child {
padding-left: 8px;
word-break: break-word;
overflow-wrap: break-word;
width: 100%;
}

View file

@ -77,7 +77,7 @@ export const SpotifyStore = proxyLazyWebpack(() => {
class SpotifyStore extends Store {
public mPosition = 0;
private start = 0;
public _start = 0;
public track: Track | null = null;
public device: Device | null = null;
@ -100,26 +100,26 @@ export const SpotifyStore = proxyLazyWebpack(() => {
public get position(): number {
let pos = this.mPosition;
if (this.isPlaying) {
pos += Date.now() - this.start;
pos += Date.now() - this._start;
}
return pos;
}
public set position(p: number) {
this.mPosition = p;
this.start = Date.now();
this._start = Date.now();
}
prev() {
this.req("post", "/previous");
this._req("post", "/previous");
}
next() {
this.req("post", "/next");
this._req("post", "/next");
}
setVolume(percent: number) {
this.req("put", "/volume", {
this._req("put", "/volume", {
query: {
volume_percent: Math.round(percent)
}
@ -131,17 +131,17 @@ export const SpotifyStore = proxyLazyWebpack(() => {
}
setPlaying(playing: boolean) {
this.req("put", playing ? "/play" : "/pause");
this._req("put", playing ? "/play" : "/pause");
}
setRepeat(state: Repeat) {
this.req("put", "/repeat", {
this._req("put", "/repeat", {
query: { state }
});
}
setShuffle(state: boolean) {
this.req("put", "/shuffle", {
this._req("put", "/shuffle", {
query: { state }
}).then(() => {
this.shuffle = state;
@ -154,7 +154,7 @@ export const SpotifyStore = proxyLazyWebpack(() => {
this.isSettingPosition = true;
return this.req("put", "/seek", {
return this._req("put", "/seek", {
query: {
position_ms: Math.round(ms)
}
@ -164,7 +164,7 @@ export const SpotifyStore = proxyLazyWebpack(() => {
});
}
private req(method: "post" | "get" | "put", route: string, data: any = {}) {
_req(method: "post" | "get" | "put", route: string, data: any = {}) {
if (this.device?.is_active)
(data.query ??= {}).device_id = this.device.id;

View file

@ -128,7 +128,7 @@ function VoiceChannelTooltip({ channel, isLocked }: VoiceChannelTooltipProps) {
);
}
interface VoiceChannelIndicatorProps {
export interface VoiceChannelIndicatorProps {
userId: string;
isActionButton?: boolean;
shouldHighlight?: boolean;

View file

@ -10,7 +10,7 @@ import adguard from "file://adguard.js?minify";
app.on("browser-window-created", (_, win) => {
win.webContents.on("frame-created", (_, { frame }) => {
frame.once("dom-ready", () => {
frame?.once("dom-ready", () => {
if (!RendererSettings.store.plugins?.YoutubeAdblock?.enabled) return;
if (frame.url.includes("youtube.com/embed/") || (frame.url.includes("discordsays") && frame.url.includes("youtube.com"))) {

View file

@ -17,7 +17,6 @@
@media(width <= 485px) {
.vc-image-modal {
display: relative;
overflow: visible;
overflow: initial;
}

View file

@ -29,7 +29,7 @@ export type GenericStore = t.FluxStore & Record<string, any>;
export const DraftType = findByPropsLazy("ChannelMessage", "SlashCommand");
export let MessageStore: Omit<Stores.MessageStore, "getMessages"> & {
export let MessageStore: Omit<Stores.MessageStore, "getMessages"> & GenericStore & {
getMessages(chanId: string): any;
};

View file

@ -496,7 +496,7 @@ export type Avatar = ComponentType<PropsWithChildren<{
}>>;
type FocusLock = ComponentType<PropsWithChildren<{
containerRef: RefObject<HTMLElement>;
containerRef: Ref<HTMLElement>;
}>>;
export type Icon = ComponentType<JSX.IntrinsicElements["svg"] & {

View file

@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { DraftType } from "@webpack/common";
import { Channel, Guild, Role } from "discord-types/general";
import { FluxDispatcher, FluxEvents } from "./utils";
@ -229,7 +228,7 @@ export class ThemeStore extends FluxStore {
}
export type useStateFromStores = <T>(
stores: t.FluxStore[],
stores: any[],
mapper: () => T,
dependencies?: any,
isEqual?: (old: T, newer: T) => boolean

View file

@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { runtimeHashMessageKey } from "@utils/intlHash";
import type { Channel } from "discord-types/general";
// eslint-disable-next-line path-alias/no-relative
@ -58,8 +57,8 @@ export const { match, P }: Pick<typeof import("ts-pattern"), "match" | "P"> = ma
export const lodash: typeof import("lodash") = findByPropsLazy("debounce", "cloneDeep");
export const i18n = mapMangledModuleLazy('defaultLocale:"en-US"', {
t: filters.byProps(runtimeHashMessageKey("DISCORD")),
intl: filters.byProps("string", "format"),
t: m => m?.[Symbol.toStringTag] === "IntlMessagesProxy",
intl: m => m != null && Object.getPrototypeOf(m)?.withFormatters != null
}, true);
export let SnowflakeUtils: t.SnowflakeUtils;

View file

@ -193,13 +193,13 @@ define(Function.prototype, "m", {
// Overwrite Webpack's defineExports function to define the export descriptors configurable.
// This is needed so we can later blacklist specific exports from Webpack search by making them non-enumerable
this.d = function (exports: object, getters: object) {
for (const key in getters) {
if (Object.hasOwn(getters, key) && !Object.hasOwn(exports, key)) {
this.d = function (exports, definition) {
for (const key in definition) {
if (Object.hasOwn(definition, key) && !Object.hasOwn(exports, key)) {
Object.defineProperty(exports, key, {
enumerable: true,
configurable: true,
get: getters[key],
get: definition[key],
});
}
}
@ -297,11 +297,6 @@ function updateExistingFactory(moduleFactories: AnyWebpackRequire["m"], moduleId
}
if (existingFactory != null) {
// Sanity check to make sure these factories are equal
if (String(newFactory) !== String(existingFactory)) {
return false;
}
// If existingFactory exists in any of the Webpack instances we track, it's either wrapped in our proxy, or it has already been required.
// In the case it is wrapped in our proxy, and the instance we are setting does not already have it, we need to make sure the instance contains our proxy too.
if (moduleFactoriesWithFactory !== moduleFactories && existingFactory[SYM_IS_PROXIED_FACTORY]) {
@ -417,9 +412,6 @@ function runFactoryWithWrap(patchedFactory: PatchedModuleFactory, thisArg: unkno
}
exports = module.exports;
if (exports == null) {
return factoryReturn;
}
if (typeof require === "function" && require.c) {
if (_blacklistBadModules(require.c, exports, module.id)) {
@ -427,6 +419,10 @@ function runFactoryWithWrap(patchedFactory: PatchedModuleFactory, thisArg: unkno
}
}
if (exports == null) {
return factoryReturn;
}
for (const callback of moduleListeners) {
try {
callback(exports, module.id);
@ -562,8 +558,13 @@ function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory):
continue;
}
const pluginsList = [...patchedBy];
if (!patchedBy.has(patch.plugin)) {
pluginsList.push(patch.plugin);
}
code = newCode;
patchedSource = `// Webpack Module ${String(moduleId)} - Patched by ${[...patchedBy, patch.plugin].join(", ")}\n${newCode}\n//# sourceURL=WebpackModule${String(moduleId)}`;
patchedSource = `// Webpack Module ${String(moduleId)} - Patched by ${pluginsList.join(", ")}\n${newCode}\n//# sourceURL=WebpackModule${String(moduleId)}`;
patchedFactory = (0, eval)(patchedSource);
if (!patchedBy.has(patch.plugin)) {

View file

@ -131,7 +131,7 @@ function shouldIgnoreValue(value: any) {
return false;
}
function makePropertyNonEnumerable(target: Object, key: PropertyKey) {
function makePropertyNonEnumerable(target: Record<PropertyKey, any>, key: PropertyKey) {
const descriptor = Object.getOwnPropertyDescriptor(target, key);
if (descriptor == null) return;
@ -499,12 +499,12 @@ export function findExportedComponentLazy<T extends object = any>(...props: Prop
});
}
function getAllPropertyNames(object: Object, includeNonEnumerable: boolean) {
function getAllPropertyNames(object: Record<PropertyKey, any>, includeNonEnumerable: boolean) {
const names = new Set<PropertyKey>();
const getKeys = includeNonEnumerable ? Object.getOwnPropertyNames : Object.keys;
do {
getKeys(object).forEach(name => names.add(name));
getKeys(object).forEach(name => name !== "__esModule" && names.add(name));
object = Object.getPrototypeOf(object);
} while (object != null);

13
src/webpack/wreq.d.ts vendored
View file

@ -17,14 +17,11 @@ export type Module = {
/** exports can be anything, however initially it is always an empty object */
export type ModuleFactory = (this: ModuleExports, module: Module, exports: ModuleExports, require: WebpackRequire) => void;
export type WebpackQueues = unique symbol | "__webpack_queues__";
export type WebpackExports = unique symbol | "__webpack_exports__";
export type WebpackError = unique symbol | "__webpack_error__";
/** Keys here can be symbols too, but we can't properly type them */
export type AsyncModulePromise = Promise<ModuleExports> & {
[WebpackQueues]: (fnQueue: ((queue: any[]) => any)) => any;
[WebpackExports]: ModuleExports;
[WebpackError]?: any;
"__webpack_queues__": (fnQueue: ((queue: any[]) => any)) => any;
"__webpack_exports__": ModuleExports;
"__webpack_error__"?: any;
};
export type AsyncModuleBody = (
@ -152,7 +149,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & {
* }
* // exports is now { exportName: someExportedValue } (but each value is actually a getter)
*/
d: (this: WebpackRequire, exports: AnyRecord, definiton: AnyRecord) => void;
d: (this: WebpackRequire, exports: Record<PropertyKey, any>, definiton: Record<PropertyKey, () => ModuleExports>) => void;
/** The ensure chunk handlers, which are used to ensure the files of the chunks are loaded, or load if necessary */
f: EnsureChunkHandlers;
/**