From 7d77a34a4f78bbb0d9f388fad4087c82cf1d088b Mon Sep 17 00:00:00 2001
From: amsyarasyiq <82711525+amsyarasyiq@users.noreply.github.com>
Date: Tue, 2 Apr 2024 22:24:56 +0800
Subject: [PATCH] [metro] Polyfill the lost redesign module
---
src/index.ts | 4 +-
src/lib/metro/filters.ts | 14 ++-
src/lib/metro/polyfills/redesign.ts | 138 ++++++++++++++++++++++++++++
src/lib/ui/index.ts | 1 +
src/lib/ui/styles.ts | 3 +-
5 files changed, 154 insertions(+), 6 deletions(-)
create mode 100644 src/lib/metro/polyfills/redesign.ts
diff --git a/src/index.ts b/src/index.ts
index cc7585e..c89bc59 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -7,7 +7,7 @@ import { patchAssets } from "@lib/api/assets";
import { patchCommands } from "@lib/api/commands";
import { injectFluxInterceptor } from "@lib/api/flux";
import { isThemeSupported } from "@lib/api/native/loader";
-import { patchLogHook } from "@lib/debug";
+import { connectToDebugger, patchLogHook } from "@lib/debug";
import { initPlugins } from "@lib/managers/plugins";
import { initThemes, patchChatBackground } from "@lib/managers/themes";
import { patchSettings } from "@lib/ui/settings";
@@ -48,6 +48,8 @@ export default async () => {
// Assign window object
window.bunny = lib;
+ connectToDebugger("127.0.0.1:9090/");
+
// Once done, load plugins
lib.unload.push(await initPlugins());
diff --git a/src/lib/metro/filters.ts b/src/lib/metro/filters.ts
index f2b6f29..a2f569f 100644
--- a/src/lib/metro/filters.ts
+++ b/src/lib/metro/filters.ts
@@ -1,5 +1,6 @@
import { after, instead } from "@lib/api/patcher";
+
export type MetroModules = { [id: string]: any; };
export type PropIntellisense
= Record
& Record;
export type PropsFinder = (...props: T[]) => PropIntellisense;
@@ -29,7 +30,6 @@ for (const id in window.modules) {
}
}
-
// Blacklist any "bad-actor" modules, e.g. the dreaded null proxy, the window itself, or undefined modules
for (const id in window.modules) {
const module = requireModule(id);
@@ -96,13 +96,19 @@ function requireModule(id: string) {
return exports;
}
+function* getModules() {
+ yield require("./polyfills/redesign");
+
+ for (const id in modules) {
+ yield requireModule(id);
+ }
+}
+
// Function to filter through modules
const filterModules = (modules: MetroModules, single = false) => (filter: (m: any) => boolean) => {
const found = [];
- for (const id in modules) {
- const exports = requireModule(id);
-
+ for (const exports of getModules()) {
if (exports.default && exports.__esModule && filter(exports.default)) {
if (single) return exports.default;
found.push(exports.default);
diff --git a/src/lib/metro/polyfills/redesign.ts b/src/lib/metro/polyfills/redesign.ts
new file mode 100644
index 0000000..0d54786
--- /dev/null
+++ b/src/lib/metro/polyfills/redesign.ts
@@ -0,0 +1,138 @@
+import "@metro/index";
+
+import { LiteralUnion } from "type-fest";
+
+const redesignProps = new Set([
+ "AlertActionButton",
+ "AlertModal",
+ "AlertModalContainer",
+ "AvatarDuoPile",
+ "AvatarPile",
+ "BACKDROP_OPAQUE_MAX_OPACITY",
+ "Backdrop",
+ "Button",
+ "Card",
+ "ContextMenu",
+ "ContextMenuContainer",
+ "FauxHeader",
+ "FloatingActionButton",
+ "GhostInput",
+ "GuildIconPile",
+ "HeaderActionButton",
+ "HeaderButton",
+ "HeaderSubmittingIndicator",
+ "IconButton",
+ "Input",
+ "InputButton",
+ "InputContainer",
+ "LayerContext",
+ "LayerScope",
+ "Modal",
+ "ModalActionButton",
+ "ModalContent",
+ "ModalDisclaimer",
+ "ModalFloatingAction",
+ "ModalFloatingActionSpacer",
+ "ModalFooter",
+ "ModalScreen",
+ "ModalStepIndicator",
+ "NAV_BAR_HEIGHT",
+ "NAV_BAR_HEIGHT_MULTILINE",
+ "Navigator",
+ "NavigatorHeader",
+ "NavigatorScreen",
+ "Pile",
+ "PileOverflow",
+ "RedesignCompat",
+ "RedesignCompatContext",
+ "RowButton",
+ "STATUS_BAR_HEIGHT",
+ "SceneLoadingIndicator",
+ "SearchField",
+ "SegmentedControl",
+ "SegmentedControlPages",
+ "Slider",
+ "Stack",
+ "StepModal",
+ "StickyContext",
+ "StickyHeader",
+ "StickyWrapper",
+ "TABLE_ROW_CONTENT_HEIGHT",
+ "TABLE_ROW_HEIGHT",
+ "TableCheckboxRow",
+ "TableRadioGroup",
+ "TableRadioRow",
+ "TableRow",
+ "TableRowGroup",
+ "TableRowGroupTitle",
+ "TableRowIcon",
+ "TableSwitchRow",
+ "Tabs",
+ "TextArea",
+ "TextField",
+ "TextInput",
+ "Toast",
+ "dismissAlerts",
+ "getHeaderBackButton",
+ "getHeaderCloseButton",
+ "getHeaderConditionalBackButton",
+ "getHeaderNoTitle",
+ "getHeaderTextButton",
+ "hideContextMenu",
+ "navigatorShouldCrossfade",
+ "openAlert",
+ "useAccessibilityNativeStackOptions",
+ "useAndroidNavScrim",
+ "useCoachmark",
+ "useFloatingActionButtonScroll",
+ "useFloatingActionButtonState",
+ "useNativeStackNavigation",
+ "useNavigation",
+ "useNavigationTheme",
+ "useNavigatorBackPressHandler",
+ "useNavigatorScreens",
+ "useNavigatorShouldCrossfade",
+ "useSegmentedControlState",
+ "useStackNavigation",
+ "useTabNavigation",
+ "useTooltip"
+] as const);
+
+type Keys = LiteralUnion ? U : string, string>;
+
+const redesignPropSource = {} as Record;
+const redesignModule = {} as Record;
+
+for (const id in window.modules) {
+ const exports = window.__r(id);
+ polyfillRedesignModule(exports);
+}
+
+function polyfillRedesignModule(exports: any) {
+ const propMap = new Map();
+
+ for (const prop of redesignProps) {
+ if (exports?.[prop]) {
+ propMap.set(prop, null);
+ }
+ else if (exports?.default?.[prop]) {
+ propMap.set(prop, "default");
+ }
+ }
+
+ for (const [prop, defaultKey] of propMap) {
+ const exportsForProp = defaultKey ? exports[defaultKey] : exports;
+
+ if (redesignModule[prop]) {
+ if (Object.keys(exportsForProp).length < Object.keys(redesignPropSource[prop]).length) {
+ redesignModule[prop] = exportsForProp[prop];
+ redesignPropSource[prop] = exportsForProp;
+ }
+ } else {
+ redesignModule[prop] = exportsForProp[prop];
+ redesignPropSource[prop] = exportsForProp;
+ }
+ }
+}
+
+export default redesignModule;
diff --git a/src/lib/ui/index.ts b/src/lib/ui/index.ts
index 824de76..a82cd14 100644
--- a/src/lib/ui/index.ts
+++ b/src/lib/ui/index.ts
@@ -1,3 +1,4 @@
+
export * as alerts from "./alerts";
export * as color from "./color";
export * as components from "./components";
diff --git a/src/lib/ui/styles.ts b/src/lib/ui/styles.ts
index 0939827..448c135 100644
--- a/src/lib/ui/styles.ts
+++ b/src/lib/ui/styles.ts
@@ -1,3 +1,4 @@
+import { findByProps } from "@lib/metro";
import { isSemanticColor, resolveSemanticColor } from "@ui/color";
import { CompatfulRedesign } from "@ui/components/discord/Redesign";
import { DiscordTextStyles } from "@ui/types";
@@ -5,7 +6,7 @@ import { ImageStyle, StyleSheet, TextStyle, ViewStyle } from "react-native";
type NamedStyles = { [P in keyof T]: ViewStyle | TextStyle | ImageStyle };
-export const { TextStyleSheet } = CompatfulRedesign as unknown as {
+export const { TextStyleSheet } = findByProps("TextStyleSheet") as unknown as {
TextStyleSheet: { [key in DiscordTextStyles]: TextStyle; };
};