refactor(metro): overall rewrite
This commit is contained in:
parent
072f189a72
commit
6d2eb7a6bf
51 changed files with 252 additions and 186 deletions
|
|
@ -67,11 +67,11 @@
|
||||||
{
|
{
|
||||||
"relativeDepth": 0,
|
"relativeDepth": 0,
|
||||||
"aliases": [
|
"aliases": [
|
||||||
{ "alias": "@lib", "matcher": "^src/lib" },
|
|
||||||
{ "alias": "@metro", "matcher": "^src/lib/metro" },
|
{ "alias": "@metro", "matcher": "^src/lib/metro" },
|
||||||
{ "alias": "@core", "matcher": "^src/core" },
|
{ "alias": "@core", "matcher": "^src/core" },
|
||||||
{ "alias": "@ui", "matcher": "^src/lib/ui" },
|
{ "alias": "@ui", "matcher": "^src/lib/ui" },
|
||||||
{ "alias": "@types", "matcher": "^src/lib/utils/types.ts" }
|
{ "alias": "@types", "matcher": "^src/lib/utils/types.ts" },
|
||||||
|
{ "alias": "@lib", "matcher": "^src/lib" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ try {
|
||||||
"transform-classes"
|
"transform-classes"
|
||||||
],
|
],
|
||||||
exclude: [
|
exclude: [
|
||||||
|
"transform-parameters",
|
||||||
"transform-async-to-generator",
|
"transform-async-to-generator",
|
||||||
"transform-exponentiation-operator",
|
"transform-exponentiation-operator",
|
||||||
"transform-named-capturing-groups-regex",
|
"transform-named-capturing-groups-regex",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { Strings } from "@core/i18n";
|
||||||
import { ApplicationCommand, ApplicationCommandOptionType } from "@lib/api/commands/types";
|
import { ApplicationCommand, ApplicationCommandOptionType } from "@lib/api/commands/types";
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { messageUtil } from "@metro/common";
|
import { messageUtil } from "@metro/common";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
|
|
||||||
const util = findByProps("inspect");
|
const util = findByProps("inspect");
|
||||||
const AsyncFunction = (async () => void 0).constructor;
|
const AsyncFunction = (async () => void 0).constructor;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { FluxDispatcher } from "@lib/metro/common";
|
import { FluxDispatcher } from "@metro/common";
|
||||||
import { findByName } from "@lib/metro/filters";
|
import { findByName } from "@metro/utils";
|
||||||
import { PrimitiveType } from "intl-messageformat";
|
import { PrimitiveType } from "intl-messageformat";
|
||||||
|
|
||||||
import langDefault from "./default.json";
|
import langDefault from "./default.json";
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import { after } from "@lib/api/patcher";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { installPlugin, plugins, removePlugin } from "@lib/managers/plugins";
|
import { installPlugin, plugins, removePlugin } from "@lib/managers/plugins";
|
||||||
import { installTheme, removeTheme, themes } from "@lib/managers/themes";
|
import { installTheme, removeTheme, themes } from "@lib/managers/themes";
|
||||||
import { ErrorBoundary } from "@lib/ui/components";
|
|
||||||
import { Button } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { DISCORD_SERVER_ID, HTTP_REGEX_MULTI, PLUGINS_CHANNEL_ID, PROXY_PREFIX, THEMES_CHANNEL_ID } from "@lib/utils/constants";
|
import { DISCORD_SERVER_ID, HTTP_REGEX_MULTI, PLUGINS_CHANNEL_ID, PROXY_PREFIX, THEMES_CHANNEL_ID } from "@lib/utils/constants";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
|
import { ErrorBoundary } from "@ui/components";
|
||||||
|
import { Button } from "@ui/components/discord/Redesign";
|
||||||
import { showToast } from "@ui/toasts";
|
import { showToast } from "@ui/toasts";
|
||||||
|
|
||||||
type PostType = "Plugin" | "Theme";
|
type PostType = "Plugin" | "Theme";
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,13 @@ import { installPlugin } from "@lib/managers/plugins";
|
||||||
import { installTheme } from "@lib/managers/themes";
|
import { installTheme } from "@lib/managers/themes";
|
||||||
import { PROXY_PREFIX, THEMES_CHANNEL_ID } from "@lib/utils/constants";
|
import { PROXY_PREFIX, THEMES_CHANNEL_ID } from "@lib/utils/constants";
|
||||||
import { channels, url } from "@metro/common";
|
import { channels, url } from "@metro/common";
|
||||||
import { find, findByProps } from "@metro/filters";
|
import { byMutableProp } from "@metro/filters";
|
||||||
|
import { find } from "@metro/finders";
|
||||||
|
import { findByProps } from "@metro/utils";
|
||||||
import { showConfirmationAlert } from "@ui/alerts";
|
import { showConfirmationAlert } from "@ui/alerts";
|
||||||
import { showToast } from "@ui/toasts";
|
import { showToast } from "@ui/toasts";
|
||||||
|
|
||||||
const showSimpleActionSheet = find(m => m?.showSimpleActionSheet && !Object.getOwnPropertyDescriptor(m, "showSimpleActionSheet")?.get);
|
const showSimpleActionSheet = find(byMutableProp("showSimpleActionSheet"));
|
||||||
const handleClick = findByProps("handleClick");
|
const handleClick = findByProps("handleClick");
|
||||||
const { openURL } = url;
|
const { openURL } = url;
|
||||||
const { getChannelId } = channels;
|
const { getChannelId } = channels;
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ import { Strings } from "@core/i18n";
|
||||||
import { CardWrapper } from "@core/ui/components/Card";
|
import { CardWrapper } from "@core/ui/components/Card";
|
||||||
import { getAssetIDByName } from "@lib/api/assets";
|
import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { findByProps } from "@lib/metro/filters";
|
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { HelpMessage } from "@lib/ui/components/discord";
|
|
||||||
import { HTTP_REGEX_MULTI } from "@lib/utils/constants";
|
import { HTTP_REGEX_MULTI } from "@lib/utils/constants";
|
||||||
import { clipboard } from "@metro/common";
|
import { clipboard } from "@metro/common";
|
||||||
|
import { findByProps } from "@metro/utils";
|
||||||
import { showInputAlert } from "@ui/alerts";
|
import { showInputAlert } from "@ui/alerts";
|
||||||
import { ErrorBoundary, Search } from "@ui/components";
|
import { ErrorBoundary, Search } from "@ui/components";
|
||||||
|
import { HelpMessage } from "@ui/components/discord";
|
||||||
import fuzzysort from "fuzzysort";
|
import fuzzysort from "fuzzysort";
|
||||||
import { createContext } from "react";
|
import { createContext } from "react";
|
||||||
import { FlatList, View } from "react-native";
|
import { FlatList, View } from "react-native";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Asset } from "@lib/api/assets";
|
import { Asset } from "@lib/api/assets";
|
||||||
import { FormRow } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { clipboard } from "@metro/common";
|
import { clipboard } from "@metro/common";
|
||||||
|
import { FormRow } from "@ui/components/discord/Forms";
|
||||||
import { showToast } from "@ui/toasts";
|
import { showToast } from "@ui/toasts";
|
||||||
import { Image } from "react-native";
|
import { Image } from "react-native";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { getAssetIDByName } from "@lib/api/assets";
|
import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { FormRow } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { FormCheckbox, FormSwitch, IconButton } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { createStyles, TextStyleSheet } from "@lib/ui/styles";
|
|
||||||
import { ReactNative as RN } from "@metro/common";
|
import { ReactNative as RN } from "@metro/common";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
import { semanticColors } from "@ui/color";
|
import { semanticColors } from "@ui/color";
|
||||||
|
import { FormRow } from "@ui/components/discord/Forms";
|
||||||
|
import { FormCheckbox, FormSwitch, IconButton } from "@ui/components/discord/Redesign";
|
||||||
|
import { createStyles, TextStyleSheet } from "@ui/styles";
|
||||||
import { ImageBackground, View } from "react-native";
|
import { ImageBackground, View } from "react-native";
|
||||||
|
|
||||||
const { hideActionSheet } = findByProps("openLazy", "hideActionSheet");
|
const { hideActionSheet } = findByProps("openLazy", "hideActionSheet");
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import { CardWrapper } from "@core/ui/components/Card";
|
||||||
import { getAssetIDByName } from "@lib/api/assets";
|
import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { FontDefinition, fonts, removeFont, selectFont } from "@lib/managers/fonts";
|
import { FontDefinition, fonts, removeFont, selectFont } from "@lib/managers/fonts";
|
||||||
import { FormCheckbox, IconButton, TableRow, TableRowGroup } from "@lib/ui/components/discord/Redesign";
|
import { FormCheckbox, IconButton, TableRow, TableRowGroup } from "@ui/components/discord/Redesign";
|
||||||
import { showToast } from "@lib/ui/toasts";
|
import { showToast } from "@ui/toasts";
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
import { Pressable, View } from "react-native";
|
import { Pressable, View } from "react-native";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { getAssetIDByName } from "@lib/api/assets";
|
import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { FormText } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { TableRow } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { clipboard } from "@metro/common";
|
import { clipboard } from "@metro/common";
|
||||||
|
import { FormText } from "@ui/components/discord/Forms";
|
||||||
|
import { TableRow } from "@ui/components/discord/Redesign";
|
||||||
import { showToast } from "@ui/toasts";
|
import { showToast } from "@ui/toasts";
|
||||||
|
|
||||||
interface VersionProps {
|
interface VersionProps {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { isFontSupported, isThemeSupported } from "@lib/api/native/loader";
|
import { isFontSupported, isThemeSupported } from "@lib/api/native/loader";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { registerSection } from "@lib/ui/settings";
|
import { registerSection } from "@ui/settings";
|
||||||
import { version } from "bunny-build";
|
import { version } from "bunny-build";
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import Version from "@core/ui/components/Version";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { getDebugInfo } from "@lib/debug";
|
import { getDebugInfo } from "@lib/debug";
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { Stack, TableRowGroup } from "@lib/ui/components/discord/Redesign";
|
import { Stack, TableRowGroup } from "@ui/components/discord/Redesign";
|
||||||
import { Platform, ScrollView } from "react-native";
|
import { Platform, ScrollView } from "react-native";
|
||||||
|
|
||||||
export default function About() {
|
export default function About() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import AssetDisplay from "@core/ui/components/AssetDisplay";
|
import AssetDisplay from "@core/ui/components/AssetDisplay";
|
||||||
import { all } from "@lib/api/assets";
|
import { all } from "@lib/api/assets";
|
||||||
import { FormDivider } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { ErrorBoundary, Search } from "@ui/components";
|
import { ErrorBoundary, Search } from "@ui/components";
|
||||||
|
import { FormDivider } from "@ui/components/discord/Forms";
|
||||||
import { FlatList, View } from "react-native";
|
import { FlatList, View } from "react-native";
|
||||||
|
|
||||||
export default function AssetBrowser() {
|
export default function AssetBrowser() {
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@ import { getReactDevToolsProp, getReactDevToolsVersion, isLoaderConfigSupported,
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { connectToDebugger } from "@lib/debug";
|
import { connectToDebugger } from "@lib/debug";
|
||||||
import { loaderConfig, settings } from "@lib/settings";
|
import { loaderConfig, settings } from "@lib/settings";
|
||||||
import { FormText } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { Button, Stack, TableRow, TableRowGroup, TableSwitchRow, TextInput } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { NavigationNative } from "@metro/common";
|
import { NavigationNative } from "@metro/common";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
import { semanticColors } from "@ui/color";
|
import { semanticColors } from "@ui/color";
|
||||||
import { ErrorBoundary } from "@ui/components";
|
import { ErrorBoundary } from "@ui/components";
|
||||||
|
import { FormText } from "@ui/components/discord/Forms";
|
||||||
|
import { Button, Stack, TableRow, TableRowGroup, TableSwitchRow, TextInput } from "@ui/components/discord/Redesign";
|
||||||
import { createStyles, TextStyleSheet } from "@ui/styles";
|
import { createStyles, TextStyleSheet } from "@ui/styles";
|
||||||
import { ScrollView, StyleSheet } from "react-native";
|
import { ScrollView, StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { createProxy, useProxy } from "@lib/api/storage";
|
import { createProxy, useProxy } from "@lib/api/storage";
|
||||||
import { FontDefinition, saveFont, validateFont } from "@lib/managers/fonts";
|
import { FontDefinition, saveFont, validateFont } from "@lib/managers/fonts";
|
||||||
import { getCurrentTheme } from "@lib/managers/themes";
|
import { getCurrentTheme } from "@lib/managers/themes";
|
||||||
import { findByProps } from "@lib/metro";
|
|
||||||
import { ErrorBoundary } from "@lib/ui/components";
|
|
||||||
import { ActionSheet, BottomSheetTitleHeader, Button, IconButton, Stack, TableRow, TableRowGroup, Text, TextInput, useNavigation } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { safeFetch } from "@lib/utils";
|
import { safeFetch } from "@lib/utils";
|
||||||
|
import { findByProps } from "@metro/utils";
|
||||||
|
import { ErrorBoundary } from "@ui/components";
|
||||||
|
import { ActionSheet, BottomSheetTitleHeader, Button, IconButton, Stack, TableRow, TableRowGroup, Text, TextInput, useNavigation } from "@ui/components/discord/Redesign";
|
||||||
import { useMemo, useRef, useState } from "react";
|
import { useMemo, useRef, useState } from "react";
|
||||||
import { ScrollView, View } from "react-native";
|
import { ScrollView, View } from "react-native";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import FontCard from "@core/ui/components/FontCard";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { FontDefinition, fonts, installFont } from "@lib/managers/fonts";
|
import { FontDefinition, fonts, installFont } from "@lib/managers/fonts";
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { FormText } from "@lib/ui/components/discord/Forms";
|
import { FormText } from "@ui/components/discord/Forms";
|
||||||
import { useNavigation } from "@lib/ui/components/discord/Redesign";
|
import { useNavigation } from "@ui/components/discord/Redesign";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { TouchableOpacity } from "react-native";
|
import { TouchableOpacity } from "react-native";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { useProxy } from "@lib/api/storage";
|
import { useProxy } from "@lib/api/storage";
|
||||||
import { getDebugInfo, toggleSafeMode } from "@lib/debug";
|
import { getDebugInfo, toggleSafeMode } from "@lib/debug";
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { Stack, TableRow, TableRowGroup, TableSwitchRow, useNavigation } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { DISCORD_SERVER, GITHUB } from "@lib/utils/constants";
|
import { DISCORD_SERVER, GITHUB } from "@lib/utils/constants";
|
||||||
import { url } from "@metro/common";
|
import { url } from "@metro/common";
|
||||||
|
import { Stack, TableRow, TableRowGroup, TableSwitchRow, useNavigation } from "@ui/components/discord/Redesign";
|
||||||
import { NativeModules, ScrollView } from "react-native";
|
import { NativeModules, ScrollView } from "react-native";
|
||||||
|
|
||||||
import About from "./About";
|
import About from "./About";
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,15 @@ import * as debug from "@lib/debug";
|
||||||
import * as plugins from "@lib/managers/plugins";
|
import * as plugins from "@lib/managers/plugins";
|
||||||
import * as themes from "@lib/managers/themes";
|
import * as themes from "@lib/managers/themes";
|
||||||
import { loaderConfig, settings } from "@lib/settings";
|
import { loaderConfig, settings } from "@lib/settings";
|
||||||
import { Forms } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { CompatfulRedesign } from "@lib/ui/components/discord/Redesign";
|
|
||||||
import { createThemedStyleSheet } from "@lib/ui/styles";
|
|
||||||
import * as utils from "@lib/utils";
|
import * as utils from "@lib/utils";
|
||||||
import * as common from "@metro/common";
|
import * as common from "@metro/common";
|
||||||
import * as metro from "@metro/filters";
|
import * as metro from "@metro/utils";
|
||||||
import * as alerts from "@ui/alerts";
|
import * as alerts from "@ui/alerts";
|
||||||
import * as color from "@ui/color";
|
import * as color from "@ui/color";
|
||||||
import * as components from "@ui/components";
|
import * as components from "@ui/components";
|
||||||
|
import { Forms } from "@ui/components/discord/Forms";
|
||||||
|
import { CompatfulRedesign } from "@ui/components/discord/Redesign";
|
||||||
|
import { createThemedStyleSheet } from "@ui/styles";
|
||||||
import * as toasts from "@ui/toasts";
|
import * as toasts from "@ui/toasts";
|
||||||
|
|
||||||
export const initVendettaObject = (): any => {
|
export const initVendettaObject = (): any => {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ async function initializeBunny() {
|
||||||
|
|
||||||
await require("@metro/caches").initMetroCache();
|
await require("@metro/caches").initMetroCache();
|
||||||
|
|
||||||
require(".").default();
|
await require(".").default();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const { ClientInfoManager } = require("@lib/api/native/modules");
|
const { ClientInfoManager } = require("@lib/api/native/modules");
|
||||||
const stack = e instanceof Error ? e.stack : undefined;
|
const stack = e instanceof Error ? e.stack : undefined;
|
||||||
|
|
|
||||||
6
src/global.d.ts
vendored
6
src/global.d.ts
vendored
|
|
@ -1,14 +1,10 @@
|
||||||
import { MetroModules } from "@lib/metro/filters";
|
|
||||||
import { BunnyObject } from "@lib/windowObject";
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var React: typeof import("react");
|
var React: typeof import("react");
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
modules: MetroModules;
|
|
||||||
vendetta: any;
|
vendetta: any;
|
||||||
bunny: BunnyObject;
|
bunny: typeof import("@lib");
|
||||||
React: typeof import("react");
|
React: typeof import("react");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import initFixes from "@core/fixes";
|
||||||
import { initFetchI18nStrings } from "@core/i18n";
|
import { initFetchI18nStrings } from "@core/i18n";
|
||||||
import { initCorePlugins } from "@core/plugins";
|
import { initCorePlugins } from "@core/plugins";
|
||||||
import initSettings from "@core/ui/settings";
|
import initSettings from "@core/ui/settings";
|
||||||
import { initVendettaObject } from "@core/vendettaObject";
|
|
||||||
import { patchCommands } from "@lib/api/commands";
|
import { patchCommands } from "@lib/api/commands";
|
||||||
import { injectFluxInterceptor } from "@lib/api/flux";
|
import { injectFluxInterceptor } from "@lib/api/flux";
|
||||||
import { removeFile, writeFile } from "@lib/api/native/fs";
|
import { removeFile, writeFile } from "@lib/api/native/fs";
|
||||||
|
|
@ -10,11 +9,10 @@ import { isPyonLoader, isThemeSupported } from "@lib/api/native/loader";
|
||||||
import { FileManager } from "@lib/api/native/modules";
|
import { FileManager } from "@lib/api/native/modules";
|
||||||
import { patchLogHook } from "@lib/debug";
|
import { patchLogHook } from "@lib/debug";
|
||||||
import { updateFonts } from "@lib/managers/fonts";
|
import { updateFonts } from "@lib/managers/fonts";
|
||||||
import { initPlugins } from "@lib/managers/plugins";
|
|
||||||
import { initThemes, patchChatBackground } from "@lib/managers/themes";
|
import { initThemes, patchChatBackground } from "@lib/managers/themes";
|
||||||
import { patchSettings } from "@lib/ui/settings";
|
|
||||||
import { logger } from "@lib/utils/logger";
|
import { logger } from "@lib/utils/logger";
|
||||||
import initSafeMode from "@ui/safeMode";
|
import initSafeMode from "@ui/safeMode";
|
||||||
|
import { patchSettings } from "@ui/settings";
|
||||||
|
|
||||||
import * as lib from "./lib";
|
import * as lib from "./lib";
|
||||||
|
|
||||||
|
|
@ -42,7 +40,7 @@ export default async () => {
|
||||||
patchLogHook(),
|
patchLogHook(),
|
||||||
patchCommands(),
|
patchCommands(),
|
||||||
patchChatBackground(),
|
patchChatBackground(),
|
||||||
initVendettaObject(),
|
// initVendettaObject(),
|
||||||
initFetchI18nStrings(),
|
initFetchI18nStrings(),
|
||||||
initSettings(),
|
initSettings(),
|
||||||
initFixes(),
|
initFixes(),
|
||||||
|
|
@ -57,7 +55,7 @@ export default async () => {
|
||||||
window.bunny = lib;
|
window.bunny = lib;
|
||||||
|
|
||||||
// Once done, load plugins
|
// Once done, load plugins
|
||||||
lib.unload.push(await initPlugins());
|
// lib.unload.push(await initPlugins());
|
||||||
|
|
||||||
// Update the fonts
|
// Update the fonts
|
||||||
updateFonts();
|
updateFonts();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// TODO: Rewrite the whole thing to fit new metro :3
|
// TODO: Rewrite the whole thing to fit new metro :3
|
||||||
|
|
||||||
import { after } from "@lib/api/patcher";
|
import { after } from "@lib/api/patcher";
|
||||||
import { getImportingModuleId, requireModule } from "@lib/metro";
|
import { getMetroCache, registerAssetCacheId } from "@metro/caches";
|
||||||
import { getMetroCache, registerAssetCacheId } from "@lib/metro/caches";
|
import { getImportingModuleId, requireModule } from "@metro/modules";
|
||||||
|
|
||||||
export const all: Record<string, Asset> = {};
|
export const all: Record<string, Asset> = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// shelter-mod inspired
|
// shelter-mod inspired
|
||||||
import { FluxDispatcher } from "@lib/metro/common";
|
import { FluxDispatcher } from "@metro/common";
|
||||||
|
|
||||||
const blockedSym = Symbol.for("bunny.flux.blocked");
|
const blockedSym = Symbol.for("bunny.flux.blocked");
|
||||||
const modifiedSym = Symbol.for("bunny.flux.modified");
|
const modifiedSym = Symbol.for("bunny.flux.modified");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import "../global.d.ts";
|
||||||
export * as api from "./api";
|
export * as api from "./api";
|
||||||
export * as debug from "./debug";
|
export * as debug from "./debug";
|
||||||
export * as managers from "./managers";
|
export * as managers from "./managers";
|
||||||
export * as metro from "./metro";
|
// export * as metro from "./metro";
|
||||||
export * as settings from "./settings";
|
export * as settings from "./settings";
|
||||||
export * as ui from "./ui";
|
export * as ui from "./ui";
|
||||||
export * as utils from "./utils";
|
export * as utils from "./utils";
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ import { awaitSyncWrapper, createFileBackend, createMMKVBackend, createStorage,
|
||||||
import { findInReactTree, safeFetch } from "@lib/utils";
|
import { findInReactTree, safeFetch } from "@lib/utils";
|
||||||
import { Author } from "@lib/utils/types";
|
import { Author } from "@lib/utils/types";
|
||||||
import { chroma } from "@metro/common";
|
import { chroma } from "@metro/common";
|
||||||
import { find, findByName, findByProps, findByStoreName } from "@metro/filters";
|
import { byMutableProp } from "@metro/filters";
|
||||||
|
import { find } from "@metro/finders";
|
||||||
|
import { findByName, findByProps, findByStoreName } from "@metro/utils";
|
||||||
import { ImageBackground, Platform, processColor } from "react-native";
|
import { ImageBackground, Platform, processColor } from "react-native";
|
||||||
|
|
||||||
export interface ThemeData {
|
export interface ThemeData {
|
||||||
|
|
@ -249,7 +251,7 @@ function isDiscordTheme(name: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function patchColor() {
|
function patchColor() {
|
||||||
const isThemeModule = find(m => m.isThemeDark && Object.getOwnPropertyDescriptor(m, "isThemeDark")?.value);
|
const isThemeModule = find(byMutableProp("isThemeDark"));
|
||||||
const callback = ([theme]: any[]) => theme === vdKey ? [vdThemeFallback] : void 0;
|
const callback = ([theme]: any[]) => theme === vdKey ? [vdThemeFallback] : void 0;
|
||||||
|
|
||||||
Object.keys(color.RawColor).forEach(k => {
|
Object.keys(color.RawColor).forEach(k => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export * as cache from "./caches";
|
|
||||||
export * as common from "./common";
|
|
||||||
export * from "./filters";
|
|
||||||
export * as filters from "./filters";
|
|
||||||
export * from "./utils";
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import type { Metro } from "@metro/types";
|
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
|
||||||
export const modules: Metro.ModuleList = window.modules;
|
|
||||||
|
|
||||||
export const metroRequire: Metro.Require = window.__r;
|
|
||||||
|
|
||||||
export const define: Metro.DefineFn = window.__d;
|
|
||||||
|
|
||||||
export const clear: Metro.ClearFn = window.__c;
|
|
||||||
|
|
||||||
export const registerSegment: Metro.RegisterSegmentFn = window.__registerSegment;
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { ButtonColors } from "@lib/utils/types";
|
import { ButtonColors } from "@lib/utils/types";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
import InputAlert, { InputAlertProps } from "@ui/components/InputAlert";
|
import InputAlert, { InputAlertProps } from "@ui/components/InputAlert";
|
||||||
|
|
||||||
const Alerts = findByProps("openLazy", "close");
|
const Alerts = findByProps("openLazy", "close");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { color } from "@lib/managers/themes";
|
import { color } from "@lib/managers/themes";
|
||||||
import { findByStoreName } from "@lib/metro/filters";
|
|
||||||
import { constants } from "@metro/common";
|
import { constants } from "@metro/common";
|
||||||
|
import { findByStoreName } from "@metro/utils";
|
||||||
|
|
||||||
//! This module is only found on 165.0+, under the assumption that iOS 165.0 is the same as Android 165.0.
|
//! This module is only found on 165.0+, under the assumption that iOS 165.0 is the same as Android 165.0.
|
||||||
//* In 167.1, most if not all traces of the old color modules were removed.
|
//* In 167.1, most if not all traces of the old color modules were removed.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { instead } from "@lib/api/patcher";
|
import { instead } from "@lib/api/patcher";
|
||||||
import { findByProps } from "@lib/metro/filters";
|
|
||||||
import { OptionalKeys } from "@lib/utils/types";
|
import { OptionalKeys } from "@lib/utils/types";
|
||||||
|
import { findByProps } from "@metro/utils";
|
||||||
import { AccessibilityInfo, Platform, View } from "react-native";
|
import { AccessibilityInfo, Platform, View } from "react-native";
|
||||||
|
|
||||||
const { ContextMenu: _ContextMenu } = findByProps("ContextMenu");
|
const { ContextMenu: _ContextMenu } = findByProps("ContextMenu");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { ButtonColors } from "@lib/utils/types";
|
import { ButtonColors } from "@lib/utils/types";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
import { Alert } from "@ui/components/discord";
|
import { Alert } from "@ui/components/discord";
|
||||||
import { FormInput } from "@ui/components/discord/Forms";
|
import { FormInput } from "@ui/components/discord/Forms";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { findByProps } from "@lib/metro";
|
import { findByProps } from "@metro/utils";
|
||||||
|
|
||||||
export const Forms = findByProps("Form", "FormSection");
|
export const Forms = findByProps("Form", "FormSection");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
import { find, findByProps } from "@lib/metro";
|
import { createFilterDefinition } from "@metro/filters";
|
||||||
import { RedesignModuleKeys } from "@lib/ui/types";
|
import { find } from "@metro/finders";
|
||||||
|
import { findByProps } from "@metro/utils";
|
||||||
|
import { RedesignModuleKeys } from "@ui/types";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
|
|
||||||
const findSingular = (prop: string) => find(m => m[prop] && Object.keys(m).length === 1)?.[prop];
|
const bySingularProp = createFilterDefinition<[string]>(
|
||||||
|
([prop], m) => m[prop] && Object.keys(m).length === 1,
|
||||||
|
prop => `pyoncord.makldlksdjks(${prop})`
|
||||||
|
);
|
||||||
|
|
||||||
|
const findSingular = (prop: string) => find(bySingularProp(prop))?.[prop];
|
||||||
|
|
||||||
export const Redesign = findByProps("TableRow") as Record<RedesignModuleKeys, any>;
|
export const Redesign = findByProps("TableRow") as Record<RedesignModuleKeys, any>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { findByDisplayName, findByName, findByProps } from "@metro/filters";
|
import { findByDisplayName, findByName, findByProps } from "@metro/utils";
|
||||||
|
|
||||||
export * as Forms from "./Forms";
|
export * as Forms from "./Forms";
|
||||||
export * as Redesign from "./Redesign";
|
export * as Redesign from "./Redesign";
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { after } from "@lib/api/patcher";
|
||||||
import { toggleSafeMode } from "@lib/debug";
|
import { toggleSafeMode } from "@lib/debug";
|
||||||
import { settings } from "@lib/settings";
|
import { settings } from "@lib/settings";
|
||||||
import { ButtonColors } from "@lib/utils/types";
|
import { ButtonColors } from "@lib/utils/types";
|
||||||
import { findByName, findByProps } from "@metro/filters";
|
import { findByName, findByProps } from "@metro/utils";
|
||||||
import { semanticColors } from "@ui/color";
|
import { semanticColors } from "@ui/color";
|
||||||
import { Codeblock, ErrorBoundary as _ErrorBoundary } from "@ui/components";
|
import { Codeblock, ErrorBoundary as _ErrorBoundary } from "@ui/components";
|
||||||
import { Button, SafeAreaView } from "@ui/components/discord";
|
import { Button, SafeAreaView } from "@ui/components/discord";
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { findByName } from "@lib/metro";
|
|
||||||
import { i18n, NavigationNative } from "@lib/metro/common";
|
|
||||||
import { FormIcon, FormRow, FormSection } from "@lib/ui/components/discord/Forms";
|
|
||||||
import { registeredSections } from "@lib/ui/settings";
|
|
||||||
import { findInReactTree } from "@lib/utils";
|
import { findInReactTree } from "@lib/utils";
|
||||||
|
import { i18n, NavigationNative } from "@metro/common";
|
||||||
|
import { findByName } from "@metro/utils";
|
||||||
|
import { FormIcon, FormRow, FormSection } from "@ui/components/discord/Forms";
|
||||||
|
import { registeredSections } from "@ui/settings";
|
||||||
import { after } from "spitroast";
|
import { after } from "spitroast";
|
||||||
|
|
||||||
import { CustomPageRenderer, wrapOnPress } from "./shared";
|
import { CustomPageRenderer, wrapOnPress } from "./shared";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { NavigationNative } from "@lib/metro/common";
|
import { NavigationNative } from "@metro/common";
|
||||||
import { findByProps } from "@lib/metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
import { ErrorBoundary } from "@lib/ui/components";
|
import { ErrorBoundary } from "@ui/components";
|
||||||
import { RowConfig } from "@lib/ui/settings";
|
import { RowConfig } from "@ui/settings";
|
||||||
|
|
||||||
const tabsNavigationRef = findByProps("getRootNavigationRef");
|
const tabsNavigationRef = findByProps("getRootNavigationRef");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { findByName, findByProps } from "@lib/metro";
|
|
||||||
import { i18n } from "@lib/metro/common";
|
|
||||||
import { registeredSections } from "@lib/ui/settings";
|
|
||||||
import { findInReactTree } from "@lib/utils";
|
import { findInReactTree } from "@lib/utils";
|
||||||
|
import { i18n } from "@metro/common";
|
||||||
|
import { findByName, findByProps } from "@metro/utils";
|
||||||
|
import { registeredSections } from "@ui/settings";
|
||||||
import { after } from "spitroast";
|
import { after } from "spitroast";
|
||||||
|
|
||||||
import { CustomPageRenderer, wrapOnPress } from "./shared";
|
import { CustomPageRenderer, wrapOnPress } from "./shared";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { findByProps } from "@lib/metro";
|
import { findByProps } from "@metro/utils";
|
||||||
import { isSemanticColor, resolveSemanticColor } from "@ui/color";
|
import { isSemanticColor, resolveSemanticColor } from "@ui/color";
|
||||||
import { CompatfulRedesign } from "@ui/components/discord/Redesign";
|
import { CompatfulRedesign } from "@ui/components/discord/Redesign";
|
||||||
import { DiscordTextStyles } from "@ui/types";
|
import { DiscordTextStyles } from "@ui/types";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Strings } from "@core/i18n";
|
import { Strings } from "@core/i18n";
|
||||||
import { getAssetIDByName } from "@lib/api/assets";
|
import { getAssetIDByName } from "@lib/api/assets";
|
||||||
import { toasts } from "@metro/common";
|
import { toasts } from "@metro/common";
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/utils";
|
||||||
import { Platform } from "react-native";
|
import { Platform } from "react-native";
|
||||||
|
|
||||||
const { uuid4 } = findByProps("uuid4");
|
const { uuid4 } = findByProps("uuid4");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { findByName } from "@metro/filters";
|
import { findByName } from "@metro/utils";
|
||||||
|
|
||||||
export type LoggerFunction = (...messages: any[]) => void;
|
export type LoggerFunction = (...messages: any[]) => void;
|
||||||
export interface Logger {
|
export interface Logger {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ let metroCache = null as unknown as MetroCacheStore;
|
||||||
export function getMetroCache() {
|
export function getMetroCache() {
|
||||||
return metroCache;
|
return metroCache;
|
||||||
}
|
}
|
||||||
window.getMetroCache = getMetroCache;
|
|
||||||
|
|
||||||
export function getFuncUniqCall() {
|
export function getFuncUniqCall() {
|
||||||
const { stack } = new Error();
|
const { stack } = new Error();
|
||||||
|
|
@ -34,18 +33,18 @@ function buildInitCache() {
|
||||||
assetsCache: {}
|
assetsCache: {}
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// Make sure all assets are cached (delay by a second
|
// Make sure all assets are cached. Delay by a second
|
||||||
// because force loading all of it crashes for some reason (it shouldn't))
|
// because force loading all of results in an unexpected crash.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
for (const id in window.modules) {
|
for (const id in window.modules) {
|
||||||
require("@metro/filters").requireModule(id);
|
require("@metro/modules").requireModule(id);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function initMetroCache() {
|
export async function initMetroCache() {
|
||||||
const rawCache = await MMKVManager.getItem(PYON_METRO_CACHE_KEY);
|
const rawCache = await MMKVManager.getItem(PYON_METRO_CACHE_KEY);
|
||||||
if (rawCache == null) return void buildInitCache();
|
if (String(1) !== "1" || rawCache == null) return void buildInitCache();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
metroCache = JSON.parse(rawCache);
|
metroCache = JSON.parse(rawCache);
|
||||||
|
|
@ -1,24 +1,29 @@
|
||||||
import { find, findByProps } from "@metro/filters";
|
import { createSimpleFilter } from "@metro/filters";
|
||||||
|
import { find } from "@metro/finders";
|
||||||
import { Dispatcher } from "@metro/types";
|
import { Dispatcher } from "@metro/types";
|
||||||
|
import { findByProps } from "@metro/utils";
|
||||||
|
|
||||||
// Discord
|
// Discord
|
||||||
export const constants = findByProps("Fonts", "Permissions");
|
export const constants = findByProps("Fonts", "Permissions");
|
||||||
export const channels = findByProps("getVoiceChannelId");
|
export const channels = findByProps("getVoiceChannelId");
|
||||||
export const i18n = findByProps("Messages");
|
export const i18n = findByProps("Messages");
|
||||||
export const url = findByProps("openURL", "openDeeplink");
|
export const url = findByProps("openURL", "openDeeplink");
|
||||||
export const toasts = find(m => m.open && m.close && !m.startDrag && !m.init && !m.openReplay && !m.setAlwaysOnTop && !m.setAccountFlag);
|
|
||||||
export const clipboard = findByProps("setString", "getString", "hasString") as typeof import("@react-native-clipboard/clipboard").default;
|
export const clipboard = findByProps("setString", "getString", "hasString") as typeof import("@react-native-clipboard/clipboard").default;
|
||||||
export const assets = findByProps("registerAsset");
|
export const assets = findByProps("registerAsset");
|
||||||
export const invites = findByProps("acceptInviteAndTransitionToInviteChannel");
|
export const invites = findByProps("acceptInviteAndTransitionToInviteChannel");
|
||||||
export const commands = findByProps("getBuiltInCommands");
|
export const commands = findByProps("getBuiltInCommands");
|
||||||
export const navigation = findByProps("pushLazy");
|
export const navigation = findByProps("pushLazy");
|
||||||
|
export const toasts = find(createSimpleFilter(
|
||||||
|
m => m.open && m.close && !m.startDrag && !m.init && !m.openReplay && !m.setAlwaysOnTop && !m.setAccountFlag,
|
||||||
|
"pyoncord.metro.common.toasts"
|
||||||
|
));
|
||||||
export const messageUtil = findByProps("sendBotMessage");
|
export const messageUtil = findByProps("sendBotMessage");
|
||||||
export const navigationStack = findByProps("createStackNavigator");
|
export const navigationStack = findByProps("createStackNavigator");
|
||||||
export const NavigationNative = findByProps("NavigationContainer");
|
export const NavigationNative = findByProps("NavigationContainer");
|
||||||
|
|
||||||
// Flux
|
// Flux
|
||||||
export const Flux = findByProps("connectStores");
|
export const Flux = findByProps("connectStores");
|
||||||
export const FluxDispatcher = findByProps("_currentDispatchActionType") as Dispatcher;
|
export const FluxDispatcher = findByProps("_interceptors") as Dispatcher;
|
||||||
|
|
||||||
// React
|
// React
|
||||||
export const React = window.React = findByProps("createElement") as typeof import("react");
|
export const React = window.React = findByProps("createElement") as typeof import("react");
|
||||||
90
src/metro/filters.ts
Normal file
90
src/metro/filters.ts
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
type Indexable = Record<PropertyKey, any>;
|
||||||
|
type ModuleExports = any;
|
||||||
|
|
||||||
|
type FilterCheckDef<A extends unknown[]> = <M extends Indexable>(args: A, m: M) => boolean;
|
||||||
|
|
||||||
|
export interface FilterFn<A extends unknown[]> {
|
||||||
|
(m: any): boolean;
|
||||||
|
filter: FilterCheckDef<A>;
|
||||||
|
args: A;
|
||||||
|
isDefault: boolean;
|
||||||
|
serialized: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterDef<A extends unknown[]> {
|
||||||
|
(...args: A): FilterFn<A>;
|
||||||
|
byDefault(...args: A): FilterFn<A>;
|
||||||
|
serializer(args: A): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createFilterDefinition<A extends unknown[]>(
|
||||||
|
fn: FilterCheckDef<A>,
|
||||||
|
serializer: (args: A) => string
|
||||||
|
): FilterDef<A> {
|
||||||
|
function createHolder<T extends Function>(func: T, args: A, isDefault: boolean) {
|
||||||
|
return Object.assign(func, {
|
||||||
|
filter: fn,
|
||||||
|
args,
|
||||||
|
isDefault,
|
||||||
|
serialized: [
|
||||||
|
isDefault && "default::",
|
||||||
|
serializer(args)
|
||||||
|
].filter(Boolean).join("")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const curried = (...args: A) => createHolder((m: ModuleExports) => fn(args, m), args, false);
|
||||||
|
const curriedDefault = (...args: A) => {
|
||||||
|
function filter(m: ModuleExports) {
|
||||||
|
return m.__esModule && m.default ? fn(args, m.default) : false;
|
||||||
|
}
|
||||||
|
return createHolder(filter, args, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return Object.assign(curried, {
|
||||||
|
byDefault: curriedDefault,
|
||||||
|
serializer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSimpleFilter(
|
||||||
|
filter: (m: ModuleExports) => boolean,
|
||||||
|
id: string
|
||||||
|
) {
|
||||||
|
return createFilterDefinition(
|
||||||
|
(_, m) => filter(m),
|
||||||
|
() => `dynamic::${id}`
|
||||||
|
)();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const byProps = createFilterDefinition<string[]>(
|
||||||
|
(props, m) => props.length === 0 ? m[props[0]] : props.every(p => m[p]),
|
||||||
|
props => `pyoncord.metro.byProps(${props.join(",")})`
|
||||||
|
);
|
||||||
|
|
||||||
|
export const byName = createFilterDefinition<[string]>(
|
||||||
|
([name], m) => m.name === name,
|
||||||
|
name => `pyoncord.metro.byName(${name})`
|
||||||
|
);
|
||||||
|
|
||||||
|
export const byDisplayName = createFilterDefinition<[string]>(
|
||||||
|
([displayName], m) => m.displayName === displayName,
|
||||||
|
name => `pyoncord.metro.byDisplayName(${name})`
|
||||||
|
);
|
||||||
|
|
||||||
|
export const byTypeName = createFilterDefinition<[string]>(
|
||||||
|
([typeName], m) => m.type?.name === typeName,
|
||||||
|
name => `pyoncord.metro.byTypeName(${name})`
|
||||||
|
);
|
||||||
|
|
||||||
|
export const byStoreName = createFilterDefinition<[string]>(
|
||||||
|
([name], m) => m.getName?.length === 0 && m.getName() === name,
|
||||||
|
name => `pyoncord.metro.byStoreName(${name})`
|
||||||
|
);
|
||||||
|
|
||||||
|
export const byMutableProp = createFilterDefinition<[string]>(
|
||||||
|
([prop], m) => m?.[prop] && !Object.getOwnPropertyDescriptor(m, prop)?.get,
|
||||||
|
prop => `pyoncord.metro.byMutableProp(${prop})`
|
||||||
|
);
|
||||||
40
src/metro/finders.ts
Normal file
40
src/metro/finders.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { getFuncUniqCall } from "./caches";
|
||||||
|
import { FilterFn } from "./filters";
|
||||||
|
import { getModules } from "./modules";
|
||||||
|
|
||||||
|
function testExports<A extends unknown[]>(moduleExports: any, filter: FilterFn<A>) {
|
||||||
|
if (moduleExports.default && moduleExports.__esModule && filter(moduleExports.default))
|
||||||
|
return moduleExports.default;
|
||||||
|
if (filter(moduleExports))
|
||||||
|
return moduleExports;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the exports of the first module where filter returns truthy, and undefined otherwise.
|
||||||
|
* @param filter find calls filter once for each enumerable module's exports until it finds one where filter returns a thruthy value.
|
||||||
|
*/
|
||||||
|
export function find<A extends unknown[]>(filter: FilterFn<A>) {
|
||||||
|
const uniq = getFuncUniqCall();
|
||||||
|
|
||||||
|
for (const [id, moduleExports] of getModules(uniq, false)) {
|
||||||
|
const testedExports = testExports(moduleExports, filter);
|
||||||
|
if (testedExports !== undefined)
|
||||||
|
return testedExports;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the exports of all modules where filter returns truthy.
|
||||||
|
* @param filter findAll calls filter once for each enumerable module's exports, adding the exports to the returned array when filter returns a thruthy value.
|
||||||
|
*/
|
||||||
|
export function findAll<A extends unknown[]>(filter: FilterFn<A>) {
|
||||||
|
const foundExports: any[] = [];
|
||||||
|
const uniq = getFuncUniqCall();
|
||||||
|
|
||||||
|
for (const [id, moduleExports] of getModules(uniq, true)) {
|
||||||
|
const testedExports = testExports(moduleExports, filter);
|
||||||
|
if (testedExports !== undefined)
|
||||||
|
foundExports.push(testedExports);
|
||||||
|
}
|
||||||
|
return foundExports;
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
import { instead } from "@lib/api/patcher";
|
import { getMetroCache } from "@metro/caches";
|
||||||
import type { Metro } from "@metro/types";
|
import { Metro } from "@metro/types";
|
||||||
import { metroRequire, modules } from "@metro/utils";
|
import { instead } from "spitroast";
|
||||||
|
|
||||||
import { getFuncUniqCall, getMetroCache, registerModuleFindCacheId } from "./caches";
|
// eslint-disable-next-line prefer-destructuring
|
||||||
|
const modules: Metro.ModuleList = window.modules;
|
||||||
export type PropIntellisense<P extends PropertyKey> = Record<P, any> & Record<PropertyKey, any>;
|
const metroRequire: Metro.Require = window.__r;
|
||||||
export type PropsFinder = <T extends PropertyKey>(...props: T[]) => PropIntellisense<T>;
|
|
||||||
export type PropsFinderAll = <T extends PropertyKey>(...props: T[]) => PropIntellisense<T>[];
|
|
||||||
|
|
||||||
metroRequire(0);
|
metroRequire(0);
|
||||||
|
|
||||||
|
|
@ -153,11 +151,15 @@ export function requireModule(id: Metro.ModuleID) {
|
||||||
return moduleExports;
|
return moduleExports;
|
||||||
}
|
}
|
||||||
|
|
||||||
function* getModules(uniqueId: string, all: boolean) {
|
export function* getModules(uniqueId: string | null, all = false) {
|
||||||
yield [-1, require("@metro/polyfills/redesign")];
|
yield [-1, require("@metro/polyfills/redesign")];
|
||||||
|
|
||||||
let cache = getMetroCache().findCache[uniqueId];
|
let cache = null;
|
||||||
if (all && !cache?._) cache = undefined;
|
|
||||||
|
if (uniqueId) {
|
||||||
|
cache = getMetroCache().findCache[uniqueId];
|
||||||
|
if (all && !cache?._) cache = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
for (const id in cache ?? modules) {
|
for (const id in cache ?? modules) {
|
||||||
const exports = requireModule(id);
|
const exports = requireModule(id);
|
||||||
|
|
@ -165,70 +167,3 @@ function* getModules(uniqueId: string, all: boolean) {
|
||||||
yield [id, exports];
|
yield [id, exports];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExportsFilter = (moduleExports: any) => unknown;
|
|
||||||
|
|
||||||
function testExports(moduleExports: any, filter: ExportsFilter) {
|
|
||||||
if (moduleExports.default && moduleExports.__esModule && filter(moduleExports.default))
|
|
||||||
return moduleExports.default;
|
|
||||||
if (filter(moduleExports))
|
|
||||||
return moduleExports;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the exports of the first module where filter returns truthy, and undefined otherwise.
|
|
||||||
* @param filter find calls filter once for each enumerable module's exports until it finds one where filter returns a thruthy value.
|
|
||||||
*/
|
|
||||||
export function find(filter: ExportsFilter) {
|
|
||||||
const uniqueId = getFuncUniqCall();
|
|
||||||
|
|
||||||
for (const [id, moduleExports] of getModules(uniqueId, false)) {
|
|
||||||
const testedExports = testExports(moduleExports, filter);
|
|
||||||
if (testedExports !== undefined) {
|
|
||||||
if (id !== -1) registerModuleFindCacheId(uniqueId, Number(id), false);
|
|
||||||
return testedExports;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the exports of all modules where filter returns truthy.
|
|
||||||
* @param filter findAll calls filter once for each enumerable module's exports, adding the exports to the returned array when filter returns a thruthy value.
|
|
||||||
*/
|
|
||||||
export function findAll(filter: ExportsFilter) {
|
|
||||||
const foundExports: any[] = [];
|
|
||||||
const uniqueId = getFuncUniqCall();
|
|
||||||
|
|
||||||
for (const [id, moduleExports] of getModules(uniqueId, true)) {
|
|
||||||
const testedExports = testExports(moduleExports, filter);
|
|
||||||
if (testedExports !== undefined) {
|
|
||||||
if (id !== -1) registerModuleFindCacheId(uniqueId, Number(id), true);
|
|
||||||
foundExports.push(testedExports);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return foundExports;
|
|
||||||
}
|
|
||||||
|
|
||||||
const propsFilter = (props: PropertyKey[]) =>
|
|
||||||
(exps: any) => props.every(p => exps[p] !== undefined);
|
|
||||||
const nameFilter = (name: string, defaultExp: boolean) => defaultExp
|
|
||||||
? (exps: any) => exps?.name === name
|
|
||||||
: (exps: any) => exps?.default?.name === name;
|
|
||||||
const dNameFilter = (displayName: string, defaultExp: boolean) => defaultExp
|
|
||||||
? (exps: any) => exps?.displayName === displayName
|
|
||||||
: (exps: any) => exps?.default?.displayName === displayName;
|
|
||||||
const tNameFilter = (typeName: string, defaultExp: boolean) => defaultExp
|
|
||||||
? (exps: any) => exps?.type?.name === typeName
|
|
||||||
: (exps: any) => exps?.default?.type?.name === typeName;
|
|
||||||
const storeFilter = (name: string) =>
|
|
||||||
(exps: any) => exps.getName && exps.getName.length === 0 && exps.getName() === name;
|
|
||||||
|
|
||||||
export const findByProps: PropsFinder = (...props) => find(propsFilter(props));
|
|
||||||
export const findByPropsAll: PropsFinderAll = (...props) => findAll(propsFilter(props));
|
|
||||||
export const findByName = (name: string, defaultExp = true) => find(nameFilter(name, defaultExp));
|
|
||||||
export const findByNameAll = (name: string, defaultExp = true) => findAll(nameFilter(name, defaultExp));
|
|
||||||
export const findByDisplayName = (displayName: string, defaultExp = true) => find(dNameFilter(displayName, defaultExp));
|
|
||||||
export const findByDisplayNameAll = (displayName: string, defaultExp = true) => findAll(dNameFilter(displayName, defaultExp));
|
|
||||||
export const findByTypeName = (typeName: string, defaultExp = true) => find(tNameFilter(typeName, defaultExp));
|
|
||||||
export const findByTypeNameAll = (typeName: string, defaultExp = true) => findAll(tNameFilter(typeName, defaultExp));
|
|
||||||
export const findByStoreName = (name: string) => find(storeFilter(name));
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getMetroCache, registerPolyfillCacheId } from "@lib/metro/caches";
|
import { getMetroCache, registerPolyfillCacheId } from "@metro/caches";
|
||||||
import { modules, requireModule } from "@metro";
|
import { getModules, requireModule } from "@metro/modules";
|
||||||
import { LiteralUnion } from "type-fest";
|
import { LiteralUnion } from "type-fest";
|
||||||
|
|
||||||
const redesignProps = new Set([
|
const redesignProps = new Set([
|
||||||
|
|
@ -104,7 +104,7 @@ const redesignPropSource = {} as Record<Keys, any>;
|
||||||
const redesignModule = {} as Record<Keys, any>;
|
const redesignModule = {} as Record<Keys, any>;
|
||||||
|
|
||||||
const cache = getMetroCache().polyfillCache.redesign_module;
|
const cache = getMetroCache().polyfillCache.redesign_module;
|
||||||
for (const id in cache ?? modules) {
|
for (const id in cache ?? getModules(null)) {
|
||||||
const moduleExports = requireModule(id);
|
const moduleExports = requireModule(id);
|
||||||
polyfillRedesignModule(moduleExports, Number(id));
|
polyfillRedesignModule(moduleExports, Number(id));
|
||||||
}
|
}
|
||||||
8
src/metro/utils.ts
Normal file
8
src/metro/utils.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { byDisplayName, byName, byProps, byStoreName, byTypeName } from "./filters";
|
||||||
|
import { find } from "./finders";
|
||||||
|
|
||||||
|
export const findByProps = (...props: string[]) => find(byProps(...props));
|
||||||
|
export const findByName = (name: string, expDefault = true) => find(expDefault ? byName(name) : byName.byDefault(name));
|
||||||
|
export const findByDisplayName = (name: string, expDefault = true) => find(expDefault ? byDisplayName(name) : byDisplayName.byDefault(name));
|
||||||
|
export const findByTypeName = (name: string, expDefault = true) => find(expDefault ? byTypeName(name) : byTypeName.byDefault(name));
|
||||||
|
export const findByStoreName = (name: string) => find(byStoreName(name));
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
"@core/*": ["./src/core/*"],
|
"@core/*": ["./src/core/*"],
|
||||||
"@lib": ["./src/lib"],
|
"@lib": ["./src/lib"],
|
||||||
"@lib/*": ["./src/lib/*"],
|
"@lib/*": ["./src/lib/*"],
|
||||||
"@metro": ["./src/lib/metro"],
|
"@metro": ["./src/metro"],
|
||||||
"@metro/*": ["./src/lib/metro/*"],
|
"@metro/*": ["./src/metro/*"],
|
||||||
"@ui": ["./src/lib/ui"],
|
"@ui": ["./src/lib/ui"],
|
||||||
"@ui/*": ["./src/lib/ui/*"],
|
"@ui/*": ["./src/lib/ui/*"],
|
||||||
"@types": ["./src/lib/utils/types.ts"],
|
"@types": ["./src/lib/utils/types.ts"],
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue