fix Vencord missing from Settings right click menu & BetterSettings

This commit is contained in:
Vendicated 2025-12-06 23:43:30 +01:00
parent 960f49bab6
commit 7098f41c5b
No known key found for this signature in database
GPG key ID: D66986BAF75ECF18
3 changed files with 63 additions and 21 deletions

View file

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

View file

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

View file

@ -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<HTMLDivElement> {
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 <Layer {...props} />;
},
transformSettingsEntries(list: SettingsEntry[]) {
const items = [{ label: null as string | null, items: [] as SettingsEntry[] }];
transformSettingsEntries(list: SettingsEntry[], keyMap: Map<string, string>) {
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<any>) {
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 (
<Menu.MenuItem
key={label}
id={label.replace(/\W/, "_")}
label={label}
key={section}
id={section.replace(/\W/, "_")}
label={section}
>
{children}
</Menu.MenuItem>