diff --git a/src/plugins/gifPaste/index.ts b/src/plugins/gifPaste/index.ts index 9ce88f9d..3e864b31 100644 --- a/src/plugins/gifPaste/index.ts +++ b/src/plugins/gifPaste/index.ts @@ -19,11 +19,9 @@ import { Devs } from "@utils/constants"; import { insertTextIntoChatInputBox } from "@utils/discord"; import definePlugin from "@utils/types"; -import { filters, mapMangledModuleLazy } from "@webpack"; +import { findByPropsLazy } from "@webpack"; -const ExpressionPickerState = mapMangledModuleLazy('name:"expression-picker-last-active-view"', { - close: filters.byCode("activeView:null", "setState") -}); +const { closeExpressionPicker } = findByPropsLazy("closeExpressionPicker"); export default definePlugin({ name: "GifPaste", @@ -41,7 +39,7 @@ export default definePlugin({ handleSelect(gif?: { url: string; }) { if (gif) { insertTextIntoChatInputBox(gif.url + " "); - ExpressionPickerState.close(); + closeExpressionPicker(); } } }); diff --git a/src/plugins/greetStickerPicker/index.tsx b/src/plugins/greetStickerPicker/index.tsx index 845c7a1b..9623d422 100644 --- a/src/plugins/greetStickerPicker/index.tsx +++ b/src/plugins/greetStickerPicker/index.tsx @@ -20,7 +20,7 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy } from "@webpack"; -import { ContextMenu, FluxDispatcher, Menu } from "@webpack/common"; +import { ContextMenuApi, FluxDispatcher, Menu } from "@webpack/common"; import { Channel, Message } from "discord-types/general"; interface Sticker { @@ -183,6 +183,6 @@ export default definePlugin({ } ) { if (!(props.message as any).deleted) - ContextMenu.open(event, () => ); + ContextMenuApi.openContextMenu(event, () => ); } }); diff --git a/src/plugins/imageZoom/index.tsx b/src/plugins/imageZoom/index.tsx index 75c944eb..c14754c8 100644 --- a/src/plugins/imageZoom/index.tsx +++ b/src/plugins/imageZoom/index.tsx @@ -23,7 +23,7 @@ import { makeRange } from "@components/PluginSettings/components"; import { Devs } from "@utils/constants"; import { debounce } from "@utils/debounce"; import definePlugin, { OptionType } from "@utils/types"; -import { ContextMenu, Menu, React, ReactDOM } from "@webpack/common"; +import { ContextMenuApi, Menu, React, ReactDOM } from "@webpack/common"; import type { Root } from "react-dom/client"; import { Magnifier, MagnifierProps } from "./components/Magnifier"; @@ -89,7 +89,7 @@ const imageContextMenuPatch: NavContextMenuPatchCallback = children => () => { checked={settings.store.square} action={() => { settings.store.square = !settings.store.square; - ContextMenu.close(); + ContextMenuApi.closeContextMenu(); }} /> () => { checked={settings.store.nearestNeighbour} action={() => { settings.store.nearestNeighbour = !settings.store.nearestNeighbour; - ContextMenu.close(); + ContextMenuApi.closeContextMenu(); }} /> { if ((settings.store as any).unsafeViewAsRole && permission.type === PermissionType.Role) - ContextMenu.open(e, () => ( + ContextMenuApi.openContextMenu(e, () => ( ) => - ContextMenu.open(e, () => ); + ContextMenuApi.openContextMenu(e, () => ); } function Controls() { @@ -277,7 +277,7 @@ function Info({ track }: { track: Track; }) { alt="Album Image" onClick={() => setCoverExpanded(!coverExpanded)} onContextMenu={e => { - ContextMenu.open(e, () => ); + ContextMenuApi.openContextMenu(e, () => ); }} /> )} diff --git a/src/utils/modal.tsx b/src/utils/modal.tsx index 1efb9cdd..6758a1a1 100644 --- a/src/utils/modal.tsx +++ b/src/utils/modal.tsx @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { filters, findByProps, findByPropsLazy, mapMangledModuleLazy } from "@webpack"; +import { findByProps, findByPropsLazy } from "@webpack"; import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react"; import { LazyComponent } from "./react"; @@ -49,13 +49,7 @@ export interface ModalOptions { type RenderFunction = (props: ModalProps) => ReactNode; -export const Modals = mapMangledModuleLazy(".closeWithCircleBackground", { - ModalRoot: filters.byCode(".root"), - ModalHeader: filters.byCode(".header"), - ModalContent: filters.byCode(".content"), - ModalFooter: filters.byCode(".footerSeparator"), - ModalCloseButton: filters.byCode(".closeWithCircleBackground"), -}) as { +export const Modals = findByPropsLazy("ModalRoot", "ModalCloseButton") as { ModalRoot: ComponentType Menu = m); -export const ContextMenu: t.ContextMenuApi = mapMangledModuleLazy('type:"CONTEXT_MENU_OPEN"', { - open: filters.byCode("stopPropagation"), - openLazy: m => m.toString().length < 50, - close: filters.byCode("CONTEXT_MENU_CLOSE") -}); +export const ContextMenuApi: t.ContextMenuApi = findByPropsLazy("closeContextMenu", "openContextMenu"); diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index 1b00180f..0c470d6a 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -19,7 +19,7 @@ import type * as Stores from "discord-types/stores"; // eslint-disable-next-line path-alias/no-relative -import { filters, findByPropsLazy, mapMangledModuleLazy } from "../webpack"; +import { findByPropsLazy } from "../webpack"; import { waitForStore } from "./internal"; import * as t from "./types/stores"; @@ -62,10 +62,6 @@ export let EmojiStore: t.EmojiStore; export let WindowStore: t.WindowStore; export let DraftStore: t.DraftStore; -export const MaskedLinkStore = mapMangledModuleLazy('"MaskedLinkStore"', { - openUntrustedLink: filters.byCode(".apply(this,arguments)") -}); - /** * React hook that returns stateful data for one or more stores * You might need a custom comparator (4th argument) if your store data is an object diff --git a/src/webpack/common/types/menu.d.ts b/src/webpack/common/types/menu.d.ts index 29f3ffae..0b8ab5c6 100644 --- a/src/webpack/common/types/menu.d.ts +++ b/src/webpack/common/types/menu.d.ts @@ -75,14 +75,14 @@ export interface Menu { } export interface ContextMenuApi { - close(): void; - open( + closeContextMenu(): void; + openContextMenu( event: UIEvent, render?: Menu["Menu"], options?: { enableSpellCheck?: boolean; }, renderLazy?: () => Promise ): void; - openLazy( + openContextMenuLazy( event: UIEvent, renderLazy?: () => Promise, options?: { enableSpellCheck?: boolean; } diff --git a/src/webpack/common/types/utils.d.ts b/src/webpack/common/types/utils.d.ts index 64a68f2c..24665914 100644 --- a/src/webpack/common/types/utils.d.ts +++ b/src/webpack/common/types/utils.d.ts @@ -161,3 +161,24 @@ export interface i18n { Messages: Record; } + +export interface Clipboard { + copy(text: string): void; + SUPPORTS_COPY: boolean; +} + +export interface NavigationRouter { + back(): void; + forward(): void; + hasNavigated(): boolean; + getHistory(): { + action: string; + length: 50; + [key: string]: any; + }; + transitionTo(path: string, ...args: unknown[]): void; + transitionToGuild(guildId: string, ...args: unknown[]): void; + replaceWith(...args: unknown[]): void; + getLastRouteChangeSource(): any; + getLastRouteChangeSourceLocationStack(): any; +} diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index 8376925e..2a3d4e67 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -20,7 +20,7 @@ import { proxyLazy } from "@utils/lazy"; import type { Channel, User } from "discord-types/general"; // eslint-disable-next-line path-alias/no-relative -import { _resolveReady, filters, find, findByPropsLazy, findLazy, mapMangledModuleLazy, waitFor } from "../webpack"; +import { _resolveReady, find, findByPropsLazy, findLazy, waitFor } from "../webpack"; import type * as t from "./types/utils"; export let FluxDispatcher: t.FluxDispatcher; @@ -102,17 +102,9 @@ export const ApplicationAssetUtils = findByPropsLazy("fetchAssetIds", "getAssetI fetchAssetIds: (applicationId: string, e: string[]) => Promise; }; -export const Clipboard = mapMangledModuleLazy('document.queryCommandEnabled("copy")||document.queryCommandSupported("copy")', { - copy: filters.byCode(".copy("), - SUPPORTS_COPY: x => typeof x === "boolean", -}); +export const Clipboard: t.Clipboard = findByPropsLazy("SUPPORTS_COPY", "copy"); -export const NavigationRouter = mapMangledModuleLazy("transitionToGuild - ", { - transitionTo: filters.byCode("transitionTo -"), - transitionToGuild: filters.byCode("transitionToGuild -"), - goBack: filters.byCode("goBack()"), - goForward: filters.byCode("goForward()"), -}); +export const NavigationRouter: t.NavigationRouter = findByPropsLazy("transitionTo", "replaceWith", "transitionToGuild"); waitFor(["dispatch", "subscribe"], m => { FluxDispatcher = m; diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts index c7be62da..b9c67e8f 100644 --- a/src/webpack/webpack.ts +++ b/src/webpack/webpack.ts @@ -312,47 +312,6 @@ export const findModuleId = traceFunction("findModuleId", function findModuleId( return null; }); -/** - * Finds a mangled module by the provided code "code" (must be unique and can be anywhere in the module) - * then maps it into an easily usable module via the specified mappers - * @param code Code snippet - * @param mappers Mappers to create the non mangled exports - * @returns Unmangled exports as specified in mappers - * - * @example mapMangledModule("headerIdIsManaged:", { - * openModal: filters.byCode("headerIdIsManaged:"), - * closeModal: filters.byCode("key==") - * }) - */ -export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule(code: string, mappers: Record): Record { - const exports = {} as Record; - - const id = findModuleId(code); - if (id === null) - return exports; - - const mod = wreq(id); - outer: - for (const key in mod) { - const member = mod[key]; - for (const newName in mappers) { - // if the current mapper matches this module - if (mappers[newName](member)) { - exports[newName] = member; - continue outer; - } - } - } - return exports; -}); - -/** - * Same as {@link mapMangledModule} but lazy - */ -export function mapMangledModuleLazy(code: string, mappers: Record): Record { - return proxyLazy(() => mapMangledModule(code, mappers)); -} - /** * Find the first module that has the specified properties */