this repo has no description
1import { InternalItem, Menu, MenuElement } from "@moonlight-mod/types/coreExtensions/contextMenu"; 2import spacepack from "@moonlight-mod/wp/spacepack_spacepack"; 3import parser from "@moonlight-mod/wp/contextMenu_evilMenu"; 4 5// NOTE: We originally had item as a function that returned this, but it didn't 6// quite know how to work out the type and thought it was a JSX element (it 7// *technically* was). This has less type safety, but a @ts-expect-error has 8// zero, so it's better than nothing. 9type ReturnType = MenuElement | MenuElement[]; 10 11type Patch = { 12 navId: string; 13 item: React.FC<any>; 14 anchor: string | RegExp; 15 before: boolean; 16}; 17 18function addItem<T = any>(navId: string, item: React.FC<T>, anchor: string | RegExp, before = false) { 19 if (anchor instanceof RegExp && anchor.flags.includes("g")) 20 throw new Error("anchor regular expression should not be global"); 21 patches.push({ navId, item, anchor, before }); 22} 23 24const patches: Patch[] = []; 25function _patchMenu(props: React.ComponentProps<Menu>, items: InternalItem[]) { 26 const matches = patches.filter((p) => p.navId === props.navId); 27 if (!matches.length) return items; 28 29 for (const patch of matches) { 30 const idx = items.findIndex((i) => 31 typeof patch.anchor === "string" ? i.key === patch.anchor : patch.anchor.test(i.key!) 32 ); 33 if (idx === -1) continue; 34 items.splice(idx + 1 - +patch.before, 0, ...parser(patch.item(menuProps) as ReturnType)); 35 } 36 37 return items; 38} 39 40let menuProps: any; 41function _saveProps(self: any, el: any) { 42 menuProps = el.props; 43 44 const original = self.props.closeContextMenu; 45 self.props.closeContextMenu = function (...args: any[]) { 46 menuProps = undefined; 47 return original?.apply(this, args); 48 }; 49 50 return el; 51} 52 53module.exports = { 54 patches, 55 addItem, 56 _patchMenu, 57 _saveProps 58}; 59 60// Unmangle Menu elements 61// spacepack.require.m[moonlight.moonmap.modules["discord/modules/menus/web/Menu"]].toString(); 62const code = 63 spacepack.require.m[ 64 spacepack.findByCode("Menu API only allows Items and groups of Items as children.")[0].id 65 ].toString(); 66 67let MangledMenu; 68 69const typeRegex = /if\(.\.type===(.)\.(.+?)\).+?type:"(.+?)"/g; 70const typeMap: Record<string, string | undefined> = { 71 checkbox: "MenuCheckboxItem", 72 control: "MenuControlItem", 73 groupstart: "MenuGroup", 74 customitem: "MenuItem", 75 radio: "MenuRadioItem", 76 separator: "MenuSeparator" 77}; 78 79for (const [, modIdent, mangled, type] of code.matchAll(typeRegex)) { 80 if (!MangledMenu) { 81 const modId = code.match(new RegExp(`${modIdent}=.\\((\\d+?)\\)`))![1]; 82 MangledMenu = spacepack.require(modId); 83 } 84 85 const prop = typeMap[type]; 86 if (!prop) continue; 87 module.exports[prop] = MangledMenu[mangled]; 88}