From 6a8564089bea162d9c4d52925eb1239b6b270fa4 Mon Sep 17 00:00:00 2001
From: Ven <vendicated@riseup.net>
Date: Mon, 7 Nov 2022 22:28:29 +0100
Subject: SpotifyControls plugin (#190)

---
 src/webpack/common.tsx | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

(limited to 'src/webpack/common.tsx')

diff --git a/src/webpack/common.tsx b/src/webpack/common.tsx
index 99f94f3..73ead1c 100644
--- a/src/webpack/common.tsx
+++ b/src/webpack/common.tsx
@@ -22,10 +22,13 @@ import type Other from "discord-types/other";
 import type Stores from "discord-types/stores";
 
 import { LazyComponent, lazyWebpack } from "../utils/misc";
-import { _resolveReady, filters, findByCode, mapMangledModuleLazy, waitFor } from "./webpack";
+import { proxyLazy } from "../utils/proxyLazy";
+import { _resolveReady, filters, findByCode, mapMangledModule, mapMangledModuleLazy, waitFor } from "./webpack";
+
 export const Margins = lazyWebpack(filters.byProps("marginTop20"));
 
 export let FluxDispatcher: Other.FluxDispatcher;
+export const Flux = lazyWebpack(filters.byProps("connectStores"));
 export let React: typeof import("react");
 export const ReactDOM: typeof import("react-dom") = lazyWebpack(filters.byProps("createPortal", "render"));
 
@@ -175,3 +178,78 @@ export type TextProps = React.PropsWithChildren & {
 };
 
 export type TextVariant = "heading-sm/normal" | "heading-sm/medium" | "heading-sm/bold" | "heading-md/normal" | "heading-md/medium" | "heading-md/bold" | "heading-lg/normal" | "heading-lg/medium" | "heading-lg/bold" | "heading-xl/normal" | "heading-xl/medium" | "heading-xl/bold" | "heading-xxl/normal" | "heading-xxl/medium" | "heading-xxl/bold" | "eyebrow" | "heading-deprecated-14/normal" | "heading-deprecated-14/medium" | "heading-deprecated-14/bold" | "text-xxs/normal" | "text-xxs/medium" | "text-xxs/semibold" | "text-xxs/bold" | "text-xs/normal" | "text-xs/medium" | "text-xs/semibold" | "text-xs/bold" | "text-sm/normal" | "text-sm/medium" | "text-sm/semibold" | "text-sm/bold" | "text-md/normal" | "text-md/medium" | "text-md/semibold" | "text-md/bold" | "text-lg/normal" | "text-lg/medium" | "text-lg/semibold" | "text-lg/bold" | "display-md" | "display-lg" | "code";
+
+type RC<C> = React.ComponentType<React.PropsWithChildren<C & Record<string, any>>>;
+interface Menu {
+    ContextMenu: RC<{
+        navId: string;
+        onClose(): void;
+        className?: string;
+        style?: React.CSSProperties;
+        hideScroller?: boolean;
+        onSelect?(): void;
+    }>;
+    MenuSeparator: React.ComponentType;
+    MenuGroup: RC<any>;
+    MenuItem: RC<{
+        id: string;
+        label: string;
+        render?: React.ComponentType;
+        onChildrenScroll?: Function;
+        childRowHeight?: number;
+        listClassName?: string;
+    }>;
+    MenuCheckboxItem: RC<{
+        id: string;
+    }>;
+    MenuRadioItem: RC<{
+        id: string;
+    }>;
+    MenuControlItem: RC<{
+        id: string;
+        interactive?: boolean;
+    }>;
+}
+
+/**
+ * Discord's Context menu items.
+ * To use anything but Menu.ContextMenu, your plugin HAS TO
+ * depend on MenuItemDeobfuscatorApi. Otherwise they will throw
+ */
+export const Menu = proxyLazy(() => {
+    const hasDeobfuscator = Vencord.Settings.plugins.MenuItemDeobfuscatorApi.enabled;
+    const menuItems = ["MenuSeparator", "MenuGroup", "MenuItem", "MenuCheckboxItem", "MenuRadioItem", "MenuControlItem"];
+
+    const map = mapMangledModule("♫ ⊂(｡◕‿‿◕｡⊂) ♪", {
+        ContextMenu: filters.byCode("getContainerProps"),
+        ...Object.fromEntries((hasDeobfuscator ? menuItems : []).map(s => [s, (m: any) => m.name === s]))
+    }) as Menu;
+
+    if (!hasDeobfuscator) {
+        for (const m of menuItems)
+            map[m] = () => {
+                throw new Error(`Your plugin needs to depend on MenuItemDeobfuscatorApi to use ${m}`);
+            };
+    }
+
+    return map;
+});
+
+export const ContextMenu = mapMangledModuleLazy('type:"CONTEXT_MENU_OPEN"', {
+    open: filters.byCode("stopPropagation"),
+    openLazy: m => m.toString().length < 50,
+    close: filters.byCode("CONTEXT_MENU_CLOSE")
+}) as {
+    close(): void;
+    open(
+        event: React.UIEvent,
+        render?: Menu["ContextMenu"],
+        options?: { enableSpellCheck?: boolean; },
+        renderLazy?: () => Promise<Menu["ContextMenu"]>
+    ): void;
+    openLazy(
+        event: React.UIEvent,
+        renderLazy?: () => Promise<Menu["ContextMenu"]>,
+        options?: { enableSpellCheck?: boolean; }
+    ): void;
+};
-- 
cgit 

