diff --git a/build.mjs b/build.mjs index 92ba9f8..a6db34f 100644 --- a/build.mjs +++ b/build.mjs @@ -18,7 +18,7 @@ console.log(`Building with commit hash "${commitHash}", isRelease=${isRelease}`) // import commitHash from "~commit-hash"; const constantsMap = { - "commit-hash": () => JSON.parse(commitHash), + "commit-hash": () => JSON.stringify(commitHash), "module-definition-hash": async () => { const defs = await readFile("src/internal-metro/requireDef.ts"); return JSON.stringify(createHash("sha256").update(defs).digest("hex")); diff --git a/src/core/api/Patcher.ts b/src/core/api/Patcher.ts index 23d6c16..08a595e 100644 --- a/src/core/api/Patcher.ts +++ b/src/core/api/Patcher.ts @@ -1,4 +1,5 @@ // this is very horrid +import { waitForModule } from "@metro"; import { after, before, instead } from "spitroast"; type Unpatcher = () => (void | boolean); @@ -14,6 +15,7 @@ export default class Patcher { identifier: string; patches: Unpatcher[] = []; stopped = false; + __contextedPatches?: Unpatcher[] = void 0; constructor(identifier: string) { if (!identifier || typeof identifier !== "string") { @@ -32,26 +34,16 @@ export default class Patcher { after = (parent: NonPrimitive, method: string, patch: AfterCallback) => this.addUnpatcher(after(method, parent, patch)); instead = (parent: NonPrimitive, method: string, patch: InsteadCallback) => this.addUnpatcher(instead(method, parent, patch)); - // private waitAndPatch

( - // patchType: P, - // filter: FilterFn, - // method: string, - // patch: Parameters[2], - // ) { - // let unpatch: Unpatcher; - // const unwaiter = waitForModule(filter, module => { - // if (this.stopped) return false; - // unpatch = this[patchType](module, method, patch); - // }); + waitAndPatch = (name: string, callback: (exports: any, module: any, id: number) => void) => { + const patches = new Array; + const cancelWait = waitForModule(name, (exp, m, id) => { + this.__contextedPatches = patches; + callback(exp, m, id); + this.__contextedPatches = undefined; + }); - // return () => (this.addUnpatcher(unwaiter), unpatch()); - // } - - // patch = (filter: FilterFn) => ({ - // before: (method: string, patch: BeforeCallback) => this.waitAndPatch("before", filter, method, patch), - // after: (method: string, patch: AfterCallback) => this.waitAndPatch("after", filter, method, patch), - // instead: (method: string, patch: InsteadCallback) => this.waitAndPatch("instead", filter, method, patch), - // }); + return () => (cancelWait(), patches.forEach(p => p?.())); + }; addUnpatcher = (callback: Unpatcher) => { if (this.stopped) return () => false; @@ -59,11 +51,12 @@ export default class Patcher { throw new Error("Unpatcher must be a function"); } + this.__contextedPatches?.push(callback); this.patches.push(callback); return callback; }; - unpatchAllAndStop() { + unpatchAllAndStop = () => { let success = true; this.stopped = true; @@ -77,5 +70,5 @@ export default class Patcher { patchesInstances.delete(this.identifier); return success; - } + }; } diff --git a/src/core/patches/experiments.ts b/src/core/patches/experiments.ts index e6fdbef..5d39342 100644 --- a/src/core/patches/experiments.ts +++ b/src/core/patches/experiments.ts @@ -6,7 +6,7 @@ const ExperimentStore = requireMetroDefaultLazy("ExperimentStore"); export default async function patchExperiments() { try { - FluxDispatcher.subscribe("CONNECTION_OPEN", () => { + const cancel = FluxDispatcher.subscribe("CONNECTION_OPEN", () => { UserStore.getCurrentUser().flags |= 1; UserStore._dispatcher._actionHandlers ._computeOrderedActionHandlers("OVERLAY_INITIALIZE") @@ -17,6 +17,8 @@ export default async function patchExperiments() { }); }); }); + + return () => cancel(); } catch (err) { console.error("An error occurred while patching experiments", err); } diff --git a/src/core/patches/idle.ts b/src/core/patches/idle.ts index 4c2be54..59127bd 100644 --- a/src/core/patches/idle.ts +++ b/src/core/patches/idle.ts @@ -13,5 +13,5 @@ export default async function patchIdle() { } }); - return patcher.unpatchAllAndStop; + return () => patcher.unpatchAllAndStop(); } diff --git a/src/core/patches/settings.tsx b/src/core/patches/settings.tsx index 7e6d75e..23a4a07 100644 --- a/src/core/patches/settings.tsx +++ b/src/core/patches/settings.tsx @@ -1,6 +1,5 @@ // Good luck reading this! import Patcher from "@api/Patcher"; -import { waitForModule } from "@metro"; import { I18n, NavigationNative, TabsNavigationRef } from "@metro/common"; import { lazyNavigate } from "@utils"; import { resolveAssets } from "@utils/assets"; @@ -16,7 +15,7 @@ const icons = resolveAssets({ // @ts-expect-error export const sections = window.__pyoncord_sections_patch = { - [`Pyoncord (${commitHash})`.trimEnd()]: [ + [`Pyoncord (${commitHash})`]: [ ["PYONCORD", "Pyoncord", () => import("@ui/screens/General"), icons.Discord], ["PYONCORD_PLUGINS", "Plugins", () => import("@ui/screens/Plugins"), icons.Wrench] ] @@ -36,7 +35,7 @@ const CustomPageRenderer = React.memo(() => { }); export default function patchSettings() { - waitForModule("SettingConstants", module => { + patcher.waitAndPatch("SettingConstants", module => { module.SETTING_RENDERER_CONFIG.PYONCORD_CUSTOM_PAGE = { type: "route", title: () => "Blah?", @@ -62,7 +61,7 @@ export default function patchSettings() { } }); - waitForModule("modules/main_tabs_v2/native/settings/renderer/SettingListRenderer.tsx", module => { + patcher.waitAndPatch("modules/main_tabs_v2/native/settings/renderer/SettingListRenderer.tsx", module => { patcher.before(module.SearchableSettingsList, "type", ([{ sections: res }]) => { if (res.__pyonMarkDirty) return; res.__pyonMarkDirty = true; diff --git a/src/core/patches/theme.ts b/src/core/patches/theme.ts deleted file mode 100644 index 676c89f..0000000 --- a/src/core/patches/theme.ts +++ /dev/null @@ -1,42 +0,0 @@ -import Patcher from "@api/Patcher"; -import { waitForModule } from "@metro"; -import { getCurrentTheme } from "@themes"; - -const patcher = new Patcher("theme-patcher"); - -// TODO: Implement theming -export default async function patchTheme() { - return; - - const currentTheme = getCurrentTheme() as any; - - waitForModule( - m => m?.unsafe_rawColors && m.meta, - ColorModule => { - let semanticColorsSymbol; - const orig_rawColors = ColorModule.unsafe_rawColors; - - ColorModule.unsafe_rawColors = { - ...ColorModule.unsafe_rawColors, - ...currentTheme.data.rawColors - }; - - patcher.addUnpatcher(() => { - ColorModule.unsafe_rawColors = orig_rawColors; - }); - - patcher.instead(ColorModule.meta, "resolveSemanticColor", ([theme, key], orig) => { - const realKey = key[semanticColorsSymbol ??= Object.getOwnPropertySymbols(key)[0]]; - const themeIndex = theme === "dark" ? 0 : theme === "light" ? 1 : 2; - - if (currentTheme.data.semanticColors[realKey]?.[themeIndex]) { - return currentTheme.data.semanticColors[realKey][themeIndex]; - } - - return orig(theme, key); - }); - } - ); - - return () => patcher.unpatchAllAndStop(); -}