aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVendicated <vendicated@riseup.net>2022-10-14 21:34:35 +0200
committerVendicated <vendicated@riseup.net>2022-10-14 21:34:35 +0200
commit296336535f6d23c586c7e83edf0420b58cbf011a (patch)
treeaa2a12bd071b36d44f43da992aa9fddfdd11bf50
parent563f2fb1dc2067345e4fbd71ce8da7d60d2928e1 (diff)
downloadVencord-296336535f6d23c586c7e83edf0420b58cbf011a.tar.gz
Vencord-296336535f6d23c586c7e83edf0420b58cbf011a.tar.bz2
Vencord-296336535f6d23c586c7e83edf0420b58cbf011a.zip
Fix modals, add wp.mapMangledModule
-rw-r--r--src/Vencord.ts1
-rw-r--r--src/plugins/petpet.ts6
-rw-r--r--src/utils/index.ts11
-rw-r--r--src/utils/misc.tsx17
-rw-r--r--src/utils/modal.tsx25
-rw-r--r--src/utils/proxyLazy.ts25
-rw-r--r--src/webpack/webpack.ts46
7 files changed, 102 insertions, 29 deletions
diff --git a/src/Vencord.ts b/src/Vencord.ts
index 9a0873e..4800621 100644
--- a/src/Vencord.ts
+++ b/src/Vencord.ts
@@ -3,6 +3,7 @@ export * as Webpack from "./webpack";
export * as Api from "./api";
export * as Updater from "./utils/updater";
export * as QuickCss from "./utils/quickCss";
+export * as Util from "./utils";
import { popNotice, showNotice } from "./api/Notices";
import { Settings, PlainSettings } from "./api/settings";
diff --git a/src/plugins/petpet.ts b/src/plugins/petpet.ts
index 0c4c29b..9d25a22 100644
--- a/src/plugins/petpet.ts
+++ b/src/plugins/petpet.ts
@@ -1,7 +1,7 @@
import { ApplicationCommandOptionType, findOption, ApplicationCommandInputType, Argument, CommandContext } from "../api/Commands";
import { Devs } from "../utils/constants";
import definePlugin from "../utils/types";
-import { lazy, lazyWebpack } from "../utils/misc";
+import { makeLazy, lazyWebpack } from "../utils/misc";
import { filters } from "../webpack";
const DRAFT_TYPE = 0;
@@ -12,9 +12,9 @@ const FRAMES = 10;
// https://github.com/mattdesl/gifenc
// this lib is way better than gif.js and all other libs, they're all so terrible but this one is nice
// @ts-ignore ts mad
-const getGifEncoder = lazy(() => import("https://unpkg.com/gifenc@1.0.3/dist/gifenc.esm.js"));
+const getGifEncoder = makeLazy(() => import("https://unpkg.com/gifenc@1.0.3/dist/gifenc.esm.js"));
-const getFrames = lazy(() => Promise.all(
+const getFrames = makeLazy(() => Promise.all(
Array.from(
{ length: FRAMES },
(_, i) => loadImage(`https://raw.githubusercontent.com/VenPlugs/petpet/main/frames/pet${i}.gif`)
diff --git a/src/utils/index.ts b/src/utils/index.ts
new file mode 100644
index 0000000..c5f4283
--- /dev/null
+++ b/src/utils/index.ts
@@ -0,0 +1,11 @@
+export * from "./ChangeList";
+export * from "./debounce";
+export * from "./misc";
+export * from "./proxyLazy";
+
+export { default as IpcEvents } from "./IpcEvents";
+export { default as Logger } from "./logger";
+
+export * as Constants from "./constants";
+export * as Discord from "./discord";
+export * as Modals from "./modal";
diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx
index b646ec1..f6ea36c 100644
--- a/src/utils/misc.tsx
+++ b/src/utils/misc.tsx
@@ -1,15 +1,17 @@
import { FilterFn, find } from "../webpack";
import { React } from "../webpack/common";
+import { proxyLazy } from "./proxyLazy";
/**
* Makes a lazy function. On first call, the value is computed.
* On subsequent calls, the same computed value will be returned
* @param factory Factory function
*/
-export function lazy<T>(factory: () => T): () => T {
+export function makeLazy<T>(factory: () => T): () => T {
let cache: T;
return () => cache ?? (cache = factory());
}
+export const lazy = makeLazy;
/**
* Do a lazy webpack search. Searches the module on first property access
@@ -17,18 +19,7 @@ export function lazy<T>(factory: () => T): () => T {
* @returns A proxy to the webpack module. Not all traps are implemented, may produce unexpected results.
*/
export function lazyWebpack<T = any>(filter: FilterFn): T {
- const getMod = lazy(() => find(filter));
-
- return new Proxy(() => null, {
- get: (_, prop) => getMod()[prop],
- set: (_, prop, value) => getMod()[prop] = value,
- has: (_, prop) => prop in getMod(),
- apply: (_, $this, args) => (getMod() as Function).apply($this, args),
- ownKeys: () => Reflect.ownKeys(getMod()),
- construct: (_, args, newTarget) => Reflect.construct(getMod(), args, newTarget),
- deleteProperty: (_, prop) => delete getMod()[prop],
- defineProperty: (_, property, attributes) => !!Object.defineProperty(getMod(), property, attributes)
- }) as any as T;
+ return proxyLazy(() => find(filter));
}
/**
diff --git a/src/utils/modal.tsx b/src/utils/modal.tsx
index b8e647c..9e5785d 100644
--- a/src/utils/modal.tsx
+++ b/src/utils/modal.tsx
@@ -1,13 +1,12 @@
-// TODO: fix
+import { filters } from "../webpack";
+import { lazyWebpack } from "./misc";
+import { mapMangledModuleLazy } from "../webpack/webpack";
-import Components from "discord-types/components";
-import { waitFor } from "../webpack";
-
-export let Modal: Components.Modal;
-export let modals: any;
-
-waitFor("openModalLazy", m => modals = m);
-waitFor("ModalRoot", m => Modal = m);
+const ModalRoot = lazyWebpack(filters.byCode("headerIdIsManaged:"));
+const Modals = mapMangledModuleLazy("onCloseRequest:null!=", {
+ openModal: filters.byCode("onCloseRequest:null!="),
+ closeModal: filters.byCode("onCloseCallback&&")
+});
let modalId = 1337;
@@ -18,10 +17,10 @@ let modalId = 1337;
*/
export function openModal(Component: React.ComponentType, modalProps: Record<string, any>) {
let key = `Vencord${modalId++}`;
- modals.openModal(props => (
- <Modal.ModalRoot {...props} {...modalProps}>
+ Modals.openModal(props => (
+ <ModalRoot {...props} {...modalProps}>
<Component />
- </Modal.ModalRoot>
+ </ModalRoot>
), { modalKey: key });
return key;
@@ -32,5 +31,5 @@ export function openModal(Component: React.ComponentType, modalProps: Record<str
* @param key The key of the modal to close
*/
export function closeModal(key: string) {
- modals.closeModal(key);
+ Modals.closeModal(key);
}
diff --git a/src/utils/proxyLazy.ts b/src/utils/proxyLazy.ts
new file mode 100644
index 0000000..0912403
--- /dev/null
+++ b/src/utils/proxyLazy.ts
@@ -0,0 +1,25 @@
+import { makeLazy } from "./misc";
+
+/**
+ * Wraps the result of {@see makeLazy} in a Proxy you can consume as if it wasn't lazy.
+ * On first property access, the lazy is evaluated
+ * @param factory lazy factory
+ * @returns Proxy
+ *
+ * Note that the example below exists already as an api, see {@link lazyWebpack}
+ * @example const mod = proxyLazy(makeLazy(() => findByProps("blah"))); console.log(mod.blah);
+ */
+export function proxyLazy<T>(factory: () => T): T {
+ const lazy = makeLazy(factory);
+
+ return new Proxy(() => null, {
+ get: (_, prop) => lazy()[prop],
+ set: (_, prop, value) => lazy()[prop] = value,
+ has: (_, prop) => prop in lazy(),
+ apply: (_, $this, args) => (lazy() as Function).apply($this, args),
+ ownKeys: () => Reflect.ownKeys(lazy() as object),
+ construct: (_, args, newTarget) => Reflect.construct(lazy() as Function, args, newTarget),
+ deleteProperty: (_, prop) => delete lazy()[prop],
+ defineProperty: (_, property, attributes) => !!Object.defineProperty(lazy(), property, attributes)
+ }) as any as T;
+}
diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts
index ca987d0..b8ccca9 100644
--- a/src/webpack/webpack.ts
+++ b/src/webpack/webpack.ts
@@ -1,4 +1,5 @@
import type { WebpackInstance } from "discord-types/other";
+import { proxyLazy } from "../utils/proxyLazy";
export let _resolveReady: () => void;
/**
@@ -92,6 +93,51 @@ export function findAll(filter: FilterFn, getDefault = true) {
return ret;
}
+/**
+ * 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 function mapMangledModule<S extends string>(code: string, mappers: Record<S, FilterFn>): Record<S, any> {
+ const exports = {} as Record<S, any>;
+
+ // search every factory function
+ for (const id in wreq.m) {
+ const src = wreq.m[id].toString() as string;
+ if (src.includes(code)) {
+ const mod = wreq(id as any as number);
+ 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;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return exports;
+}
+
+/**
+ * Same as {@link mapMangledModule} but lazy
+ */
+export function mapMangledModuleLazy<S extends string>(code: string, mappers: Record<S, FilterFn>): Record<S, any> {
+ return proxyLazy(() => mapMangledModule(code, mappers));
+}
+
export function findByProps(...props: string[]) {
return find(filters.byProps(props));
}