From f9c404c229af828b362086ae954252647c80b208 Mon Sep 17 00:00:00 2001
From: thororen <78185467+thororen1234@users.noreply.github.com>
Date: Mon, 9 Feb 2026 19:19:17 -0500
Subject: [PATCH 1/2] fix StartupTimings & Decor (#3963)
---
src/components/Icons.tsx | 16 ++++++++++++++
src/plugins/_core/settings.tsx | 21 ++++++++++--------
src/plugins/decor/index.tsx | 2 +-
src/plugins/startupTimings/index.tsx | 33 ++++++++++++++++------------
4 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx
index 877eb89de..6e39f3f49 100644
--- a/src/components/Icons.tsx
+++ b/src/components/Icons.tsx
@@ -570,3 +570,19 @@ export function CloudUploadIcon(props: IconProps) {
);
}
+
+export const ClockIcon = (props?: any) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx
index d9bcf95fb..0c61e54c3 100644
--- a/src/plugins/_core/settings.tsx
+++ b/src/plugins/_core/settings.tsx
@@ -92,6 +92,16 @@ const settings = definePluginSettings({
}
});
+const settingsSectionMap: [string, string][] = [
+ ["VencordSettings", "vencord_main_panel"],
+ ["VencordPlugins", "vencord_plugins_panel"],
+ ["VencordThemes", "vencord_themes_panel"],
+ ["VencordUpdater", "vencord_updater_panel"],
+ ["VencordCloud", "vencord_cloud_panel"],
+ ["VencordBackupAndRestore", "vencord_backup_restore_panel"],
+ ["VencordPatchHelper", "vencord_patch_helper_panel"]
+];
+
export default definePlugin({
name: "Settings",
description: "Adds Settings UI and debug info",
@@ -99,6 +109,7 @@ export default definePlugin({
required: true,
settings,
+ settingsSectionMap,
patches: [
{
@@ -205,15 +216,7 @@ export default definePlugin({
},
getSettingsSectionMappings() {
- return [
- ["VencordSettings", "vencord_main_panel"],
- ["VencordPlugins", "vencord_plugins_panel"],
- ["VencordThemes", "vencord_themes_panel"],
- ["VencordUpdater", "vencord_updater_panel"],
- ["VencordCloud", "vencord_cloud_panel"],
- ["VencordBackupAndRestore", "vencord_backup_restore_panel"],
- ["VencordPatchHelper", "vencord_patch_helper_panel"]
- ];
+ return settingsSectionMap;
},
buildLayout(originalLayoutBuilder: SettingsLayoutBuilder) {
diff --git a/src/plugins/decor/index.tsx b/src/plugins/decor/index.tsx
index c4888b94b..854f9062c 100644
--- a/src/plugins/decor/index.tsx
+++ b/src/plugins/decor/index.tsx
@@ -108,7 +108,7 @@ export default definePlugin({
replace: "$self.useUserDecorAvatarDecoration($2)??$1"
},
{
- match: /(?<=userValue:)((\i)(?:.{0,10})?\.avatarDecoration)/,
+ match: /(?<=userValue:)((\i(?:\.author)?)\?\.avatarDecoration)/,
replace: "$self.useUserDecorAvatarDecoration($2)??$1"
}
]
diff --git a/src/plugins/startupTimings/index.tsx b/src/plugins/startupTimings/index.tsx
index ede9dcd6e..2a8eac3c0 100644
--- a/src/plugins/startupTimings/index.tsx
+++ b/src/plugins/startupTimings/index.tsx
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import { ClockIcon } from "@components/Icons";
+import SettingsPlugin from "@plugins/_core/settings";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
@@ -25,18 +27,21 @@ export default definePlugin({
name: "StartupTimings",
description: "Adds Startup Timings to the Settings menu",
authors: [Devs.Megu],
-
- patches: [{
- find: ".SEARCH_NO_RESULTS&&0===",
- replacement: [
- {
- match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+\)\)\}\))(?=\)\})/,
- replace: (_, commaOrSemi, settings, elements) => "" +
- `${commaOrSemi}${settings}?.[0]==="EXPERIMENTS"` +
- `&&${elements}.push({section:"StartupTimings",label:"Startup Timings",element:$self.StartupTimingPage})`,
- },
- ]
- }],
-
- StartupTimingPage
+ start() {
+ SettingsPlugin.customEntries.push({
+ key: "vencord_startup_timings",
+ title: "Startup Timings",
+ Component: StartupTimingPage,
+ Icon: ClockIcon
+ });
+ SettingsPlugin.settingsSectionMap.push(["VencordStartupTimings", "vencord_startup_timings"]);
+ },
+ stop() {
+ function removeFromArray(arr: T[], predicate: (e: T) => boolean) {
+ const idx = arr.findIndex(predicate);
+ if (idx !== -1) arr.splice(idx, 1);
+ }
+ removeFromArray(SettingsPlugin.customEntries, e => e.key === "vencord_startup_timings");
+ removeFromArray(SettingsPlugin.settingsSectionMap, entry => entry[1] === "vencord_startup_timings");
+ },
});
From 38c490533b72a3da113b0cd0b802b8310aef2d95 Mon Sep 17 00:00:00 2001
From: Vendicated
Date: Tue, 10 Feb 2026 01:30:30 +0100
Subject: [PATCH 2/2] remove some legacy code
---
src/plugins/_core/settings.tsx | 119 ---------------------------------
src/plugins/decor/index.tsx | 14 ++--
src/webpack/patchWebpack.ts | 10 ++-
3 files changed, 11 insertions(+), 132 deletions(-)
diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx
index 0c61e54c3..55d6d7d18 100644
--- a/src/plugins/_core/settings.tsx
+++ b/src/plugins/_core/settings.tsx
@@ -20,7 +20,6 @@ import { definePluginSettings } from "@api/Settings";
import { BackupRestoreIcon, CloudIcon, MainSettingsIcon, PaintbrushIcon, PatchHelperIcon, PlaceholderIcon, PluginsIcon, UpdaterIcon, VesktopSettingsIcon } from "@components/Icons";
import { BackupAndRestoreTab, CloudTab, PatchHelperTab, PluginsTab, ThemesTab, UpdaterTab, VencordTab } from "@components/settings/tabs";
import { Devs } from "@utils/constants";
-import { getIntlMessage } from "@utils/discord";
import { isTruthy } from "@utils/guards";
import definePlugin, { IconProps, OptionType } from "@utils/types";
import { waitFor } from "@webpack";
@@ -135,19 +134,6 @@ export default definePlugin({
}
]
},
- {
- find: ".SEARCH_NO_RESULTS&&0===",
- replacement: [
- {
- match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/,
- replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
- },
- {
- match: /({(?=.+?function (\i).{0,160}(\i)=\i\.useMemo.{0,140}return \i\.useMemo\(\(\)=>\i\(\3).+?\(\)=>)\2/,
- replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
- }
- ]
- },
{
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
replacement: {
@@ -325,111 +311,6 @@ export default definePlugin({
customSections: [] as ((SectionTypes: SectionTypes) => any)[],
customEntries: [] as EntryOptions[],
- makeSettingsCategories(SectionTypes: SectionTypes) {
- return [
- {
- section: SectionTypes.HEADER,
- label: "Vencord",
- className: "vc-settings-header"
- },
- {
- section: "VencordSettings",
- label: "Vencord",
- element: VencordTab,
- className: "vc-settings"
- },
- {
- section: "VencordPlugins",
- label: "Plugins",
- element: PluginsTab,
- className: "vc-plugins"
- },
- {
- section: "VencordThemes",
- label: "Themes",
- element: ThemesTab,
- className: "vc-themes"
- },
- !IS_UPDATER_DISABLED && {
- section: "VencordUpdater",
- label: "Updater",
- element: UpdaterTab,
- className: "vc-updater"
- },
- {
- section: "VencordCloud",
- label: "Cloud",
- element: CloudTab,
- className: "vc-cloud"
- },
- {
- section: "VencordBackupAndRestore",
- label: "Backup & Restore",
- element: BackupAndRestoreTab,
- className: "vc-backup-restore"
- },
- IS_DEV && {
- section: "VencordPatchHelper",
- label: "Patch Helper",
- element: PatchHelperTab,
- className: "vc-patch-helper"
- },
- ...this.customSections.map(func => func(SectionTypes)),
- {
- section: SectionTypes.DIVIDER
- }
- ].filter(Boolean);
- },
-
- isRightSpot({ header, settings: s }: { header?: string; settings?: string[]; }) {
- const firstChild = s?.[0];
- // lowest two elements... sanity backup
- if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true;
-
- const { settingsLocation } = settings.store;
-
- if (settingsLocation === "bottom") return firstChild === "LOGOUT";
- if (settingsLocation === "belowActivity") return firstChild === "CHANGELOG";
-
- if (!header) return;
-
- try {
- const names: Record, string> = {
- top: getIntlMessage("USER_SETTINGS"),
- aboveNitro: getIntlMessage("BILLING_SETTINGS"),
- belowNitro: getIntlMessage("APP_SETTINGS"),
- aboveActivity: getIntlMessage("ACTIVITY_SETTINGS")
- };
-
- if (!names[settingsLocation] || names[settingsLocation].endsWith("_SETTINGS"))
- return firstChild === "PREMIUM";
-
- return header === names[settingsLocation];
- } catch {
- return firstChild === "PREMIUM";
- }
- },
-
- patchedSettings: new WeakSet(),
-
- addSettings(elements: any[], element: { header?: string; settings: string[]; }, sectionTypes: SectionTypes) {
- if (this.patchedSettings.has(elements) || !this.isRightSpot(element)) return;
-
- this.patchedSettings.add(elements);
-
- elements.push(...this.makeSettingsCategories(sectionTypes));
- },
-
- wrapSettingsHook(originalHook: (...args: any[]) => Record[]) {
- return (...args: any[]) => {
- const elements = originalHook(...args);
- if (!this.patchedSettings.has(elements))
- elements.unshift(...this.makeSettingsCategories(FallbackSectionTypes));
-
- return elements;
- };
- },
-
get electronVersion() {
return VencordNative.native.getVersions().electron || window.legcord?.electron || null;
},
diff --git a/src/plugins/decor/index.tsx b/src/plugins/decor/index.tsx
index 854f9062c..abf5ea460 100644
--- a/src/plugins/decor/index.tsx
+++ b/src/plugins/decor/index.tsx
@@ -102,16 +102,10 @@ export default definePlugin({
"#{intl::ayozFl::raw}", // Avatar preview
].map(find => ({
find,
- replacement: [
- {
- match: /(?<=userValue.{0,25}void 0:)((\i)\.avatarDecoration)/,
- replace: "$self.useUserDecorAvatarDecoration($2)??$1"
- },
- {
- match: /(?<=userValue:)((\i(?:\.author)?)\?\.avatarDecoration)/,
- replace: "$self.useUserDecorAvatarDecoration($2)??$1"
- }
- ]
+ replacement: {
+ match: /(?<=userValue:)((\i(?:\.author)?)\?\.avatarDecoration)/,
+ replace: "$self.useUserDecorAvatarDecoration($2)??$1"
+ }
})),
// Patch avatar decoration preview to display Decor avatar decorations as if they are purchased
{
diff --git a/src/webpack/patchWebpack.ts b/src/webpack/patchWebpack.ts
index 1eeb10ed3..c6eece366 100644
--- a/src/webpack/patchWebpack.ts
+++ b/src/webpack/patchWebpack.ts
@@ -599,10 +599,14 @@ function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory):
markedAsPatched = true;
}
} catch (err) {
- logger.error(`Patch by ${patch.plugin} errored (Module id is ${String(moduleId)}): ${replacement.match}\n`, err);
+ // FIXME: Maybe fix this properly
+ const shouldSuppressError = patch.plugin === "ContextMenuAPI" && err instanceof SyntaxError && err.message.includes("arguments");
+ if (!shouldSuppressError) {
+ logger.error(`Patch by ${patch.plugin} errored (Module id is ${String(moduleId)}): ${replacement.match}\n`, err);
- if (IS_DEV) {
- diffErroredPatch(code, lastCode, lastCode.match(replacement.match)!);
+ if (IS_DEV) {
+ diffErroredPatch(code, lastCode, lastCode.match(replacement.match)!);
+ }
}
if (markedAsPatched) {