From 7098f41c5bbe76edd62151042e4bd7c7d15ac2f6 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 6 Dec 2025 23:43:30 +0100 Subject: [PATCH] fix Vencord missing from Settings right click menu & BetterSettings --- src/plugins/_core/settings.tsx | 23 ++++++++- .../betterSettings/fullHeightContext.css | 10 ++++ src/plugins/betterSettings/index.tsx | 51 ++++++++++++------- 3 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 src/plugins/betterSettings/fullHeightContext.css diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx index fe3c792ac..63a85c72c 100644 --- a/src/plugins/_core/settings.tsx +++ b/src/plugins/_core/settings.tsx @@ -149,6 +149,13 @@ export default definePlugin({ match: /(\i)\.buildLayout\(\)(?=\.map)/, replace: "$self.buildLayout($1)" } + }, + { + find: "getWebUserSettingFromSection", + replacement: { + match: /new Map\(\[(?=\[.{0,10}\.ACCOUNT,.{0,10}\.ACCOUNT_PANEL)/, + replace: "new Map([...$self.getSettingsSectionMappings()," + } } ], @@ -180,6 +187,18 @@ 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"] + ]; + }, + buildLayout(originalLayoutBuilder: SettingsLayoutBuilder) { const layout = originalLayoutBuilder.buildLayout(); if (originalLayoutBuilder.key !== "$Root") return layout; @@ -294,7 +313,7 @@ export default definePlugin({ className: "vc-settings-header" }, { - section: "settings/tabs", + section: "VencordSettings", label: "Vencord", element: VencordTab, className: "vc-settings" @@ -324,7 +343,7 @@ export default definePlugin({ className: "vc-cloud" }, { - section: "settings/tabsSync", + section: "VencordBackupAndRestore", label: "Backup & Restore", element: BackupAndRestoreTab, className: "vc-backup-restore" diff --git a/src/plugins/betterSettings/fullHeightContext.css b/src/plugins/betterSettings/fullHeightContext.css new file mode 100644 index 000000000..97069dc9c --- /dev/null +++ b/src/plugins/betterSettings/fullHeightContext.css @@ -0,0 +1,10 @@ +/* + * Discord has dumb max height logic for their context menus. + * If a context menu is at the bottom of the screen, its submenus are capped to its max height and can't even grow upwards + * We unset the variable they use to cap height. This allows submenus to grow as tall as they want + */ + +#user-settings-cog, +[aria-activedescendant^="user-settings-cog"] { + --reference-position-layer-max-height: initial !important; +} \ No newline at end of file diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index ab2700e7c..c3432ab87 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -5,16 +5,17 @@ */ import { definePluginSettings } from "@api/Settings"; -import { classNameFactory } from "@api/Styles"; +import { classNameFactory, disableStyle, enableStyle } from "@api/Styles"; import { buildPluginMenuEntries, buildThemeMenuEntries } from "@plugins/vencordToolbox/menu"; import { Devs } from "@utils/constants"; -import { getIntlMessage } from "@utils/discord"; import { Logger } from "@utils/Logger"; import definePlugin, { OptionType } from "@utils/types"; import { waitFor } from "@webpack"; import { ComponentDispatch, FocusLock, Menu, useEffect, useRef } from "@webpack/common"; import type { HTMLAttributes, ReactElement } from "react"; +import fullHeightStyle from "./fullHeightContext.css?managed"; + type SettingsEntry = { section: string, label: string; }; const cl = classNameFactory(""); @@ -42,6 +43,11 @@ const settings = definePluginSettings({ } }); +interface TransformedSettingsEntry { + section: string; + items: SettingsEntry[]; +} + interface LayerProps extends HTMLAttributes { mode: "SHOWN" | "HIDDEN"; baseLayer?: boolean; @@ -81,6 +87,15 @@ export default definePlugin({ authors: [Devs.Kyuuhachi], settings, + start() { + if (settings.store.organizeMenu) + enableStyle(fullHeightStyle); + }, + + stop() { + disableStyle(fullHeightStyle); + }, + patches: [ { find: "this.renderArtisanalHack()", @@ -124,8 +139,8 @@ export default definePlugin({ find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}", replacement: [ { - match: /=\[\];if\((\i)(?=\.forEach)/, - replace: "=$self.wrapMap([]);if($self.transformSettingsEntries($1)", + match: /=\[\];if\((\i)(?=\.forEach.{0,100}"logout"!==\i.{0,30}(\i)\.get\(\i\))/, + replace: "=$self.wrapMap([]);if($self.transformSettingsEntries($1,$2)", predicate: () => settings.store.organizeMenu }, { @@ -154,36 +169,34 @@ export default definePlugin({ return ; }, - transformSettingsEntries(list: SettingsEntry[]) { - const items = [{ label: null as string | null, items: [] as SettingsEntry[] }]; + transformSettingsEntries(list: SettingsEntry[], keyMap: Map) { + const items = [] as TransformedSettingsEntry[]; for (const item of list) { if (item.section === "HEADER") { - items.push({ label: item.label, items: [] }); - } else if (item.section === "DIVIDER") { - items.push({ label: getIntlMessage("OTHER_OPTIONS"), items: [] }); - } else { - items.at(-1)!.items.push(item); + keyMap.set(item.label, item.label); + items.push({ section: item.label, items: [] }); + } else if (item.section !== "DIVIDER" && keyMap.has(item.section)) { + items.at(-1)?.items.push(item); } } return items; }, - wrapMap(toWrap: any[]) { - const otherOptions = getIntlMessage("OTHER_OPTIONS"); + wrapMap(toWrap: TransformedSettingsEntry[]) { // @ts-expect-error toWrap.map = function (render: (item: SettingsEntry) => ReactElement) { return this - .filter(a => a.items.length > 0 && a.label !== otherOptions) - .map(({ label, items }) => { + .filter(a => a.items.length > 0) + .map(({ section, items }) => { const children = items.map(render); - if (label) { + if (section) { return ( {children}