diff --git a/src/def.d.ts b/src/def.d.ts index 503d873..d7a5f87 100644 --- a/src/def.d.ts +++ b/src/def.d.ts @@ -46,7 +46,7 @@ interface Asset { id: number; } -declare enum ButtonColors { +export enum ButtonColors { BRAND = "brand", RED = "red", GREEN = "green", @@ -121,7 +121,7 @@ interface ApplicationCommand { type: ApplicationCommandType; } -declare enum ApplicationCommandInputType { +export enum ApplicationCommandInputType { BUILT_IN, BUILT_IN_TEXT, BUILT_IN_INTEGRATION, @@ -138,7 +138,7 @@ interface ApplicationCommandOption { displayDescription: string; } -declare enum ApplicationCommandOptionType { +export enum ApplicationCommandOptionType { SUB_COMMAND = 1, SUB_COMMAND_GROUP, STRING, @@ -152,7 +152,7 @@ declare enum ApplicationCommandOptionType { ATTACHMENT, } -declare enum ApplicationCommandType { +export enum ApplicationCommandType { CHAT = 1, USER, MESSAGE, diff --git a/src/lib/debug.ts b/src/lib/debug.ts index 679a2c0..0ed7a44 100644 --- a/src/lib/debug.ts +++ b/src/lib/debug.ts @@ -7,19 +7,16 @@ import logger from "@lib/logger"; export let socket: WebSocket; export function connectToDebugger(url: string) { - if (socket !== undefined && socket.readyState !== WebSocket.CLOSED) { - socket.close(); - } + if (socket !== undefined && socket.readyState !== WebSocket.CLOSED) socket.close(); - if (url === "") { + if (!url) { showToast("Invalid debugger URL!", getAssetIDByName("Small")); return; } socket = new WebSocket(`ws://${url}`); - + socket.addEventListener("open", () => showToast("Connected to debugger.", getAssetIDByName("Check"))); - socket.addEventListener("message", (message: any) => { try { (0, eval)(message.data); diff --git a/src/lib/emitter.ts b/src/lib/emitter.ts index 9128305..1bfbc08 100644 --- a/src/lib/emitter.ts +++ b/src/lib/emitter.ts @@ -1,10 +1,10 @@ import { Emitter, EmitterEvent, EmitterListener, EmitterListenerData, EmitterListeners } from "@types"; -export const Events = Object.freeze({ - GET: "GET", - SET: "SET", - DEL: "DEL", -}); +export enum Events { + GET = "GET", + SET = "SET", + DEL = "DEL", +}; export default function createEmitter(): Emitter { return { diff --git a/src/lib/metro/hoist.ts b/src/lib/metro/hoist.ts index 51f8466..fa06c3a 100644 --- a/src/lib/metro/hoist.ts +++ b/src/lib/metro/hoist.ts @@ -5,10 +5,10 @@ const basicFind = (prop: string) => Object.values(window.modules).find(m => m?.publicModule.exports?.[prop])?.publicModule?.exports; // Hoist React on window -window.React = basicFind("createElement") as typeof import("react");; +window.React = basicFind("createElement") as typeof import("react"); // Export ReactNative -export const ReactNative = basicFind("Text") as typeof import("react-native"); +export const ReactNative = basicFind("AppRegistry") as typeof import("react-native"); // Export Discord's constants export const constants = basicFind("AbortCodes"); diff --git a/src/lib/settings.ts b/src/lib/settings.ts index 04ef89b..4eea331 100644 --- a/src/lib/settings.ts +++ b/src/lib/settings.ts @@ -1,5 +1,5 @@ -import { createFileBackend, createMMKVBackend, createStorage, wrapSync } from "@lib/storage"; import { LoaderConfig, Settings } from "@types"; +import { createFileBackend, createMMKVBackend, createStorage, wrapSync } from "@lib/storage"; export default wrapSync(createStorage(createMMKVBackend("VENDETTA_SETTINGS"))); export const loaderConfig = wrapSync(createStorage(createFileBackend("vendetta_loader.json"))); diff --git a/src/lib/utils/copyText.ts b/src/lib/utils/copyText.ts index dd3ec15..7454477 100644 --- a/src/lib/utils/copyText.ts +++ b/src/lib/utils/copyText.ts @@ -1,5 +1,7 @@ import { clipboard } from "@metro/common"; +// TODO: Remove/deprecate this, the clipboard module works the same way. + export default function copyText(content: string) { try { clipboard.setString(content); diff --git a/src/lib/utils/unfreeze.ts b/src/lib/utils/unfreeze.ts index 3bcdbc7..c1a2e32 100644 --- a/src/lib/utils/unfreeze.ts +++ b/src/lib/utils/unfreeze.ts @@ -1,8 +1,6 @@ // https://stackoverflow.com/a/68339174 export default function unfreeze(obj: object) { - if (Object.isFrozen(obj)) { - return Object.assign({}, obj); - } + if (Object.isFrozen(obj)) return Object.assign({}, obj); return obj; } \ No newline at end of file diff --git a/src/ui/alerts.ts b/src/ui/alerts.ts index 4f1da59..be6cc4a 100644 --- a/src/ui/alerts.ts +++ b/src/ui/alerts.ts @@ -4,7 +4,7 @@ import InputAlert from "@ui/components/InputAlert"; const Alerts = findByProps("openLazy", "close"); -interface InternalConfirmationAlertOptions extends Omit { +interface InternalConfirmationAlertOptions extends Omit { content: string | JSX.Element | JSX.Element[] | undefined; body: string | undefined; children: JSX.Element | JSX.Element[]; @@ -20,18 +20,11 @@ export function showConfirmationAlert(options: ConfirmationAlertOptions) { }; delete internalOptions.content; - return Alerts.show(internalOptions); }; -export function showCustomAlert(component: React.ComponentType, props: any) { - Alerts.openLazy({ - importer: async function () { - return () => React.createElement(component, props); - } - }); -}; +export const showCustomAlert = (component: React.ComponentType, props: any) => Alerts.openLazy({ + importer: async () => () => React.createElement(component, props), +}); -export function showInputAlert(options: InputAlertProps) { - showCustomAlert(InputAlert as React.ComponentType, options); -}; \ No newline at end of file +export const showInputAlert = (options: InputAlertProps) => showCustomAlert(InputAlert as React.ComponentType, options); \ No newline at end of file diff --git a/src/ui/assets.ts b/src/ui/assets.ts index 1c31ff8..8527735 100644 --- a/src/ui/assets.ts +++ b/src/ui/assets.ts @@ -1,6 +1,6 @@ import { Asset, Indexable } from "@types"; -import { after } from "@lib/patcher"; import { assets } from "@metro/common"; +import { after } from "@lib/patcher"; export const all: Indexable = {}; diff --git a/src/ui/color.ts b/src/ui/color.ts index 571d54f..dd83a43 100644 --- a/src/ui/color.ts +++ b/src/ui/color.ts @@ -5,13 +5,13 @@ import { constants } from "@metro/hoist"; //* In 167.1, most if not all traces of the old color modules were removed. //* In 168.6, Discord restructured EVERYTHING again. SemanticColor on this module no longer works when passed to a stylesheet. We must now use what you see below. //? However, this is not all bad. The changes made in 168.6 do allow for better native-less theming. -const colorModule = findByProps("SemanticColor"); +const colorModule = findByProps("colors", "meta"); //* For both below, SemanticColor and RawColor are seemingly not used. Once again, what are Discord doing? //? SemanticColor and default.colors are effectively ThemeColorMap -export const semanticColors = (constants.ThemeColorMap ?? colorModule?.default?.colors ?? colorModule?.SemanticColor); +export const semanticColors = (constants.ThemeColorMap ?? colorModule?.colors); //? RawColor and default.unsafe_rawColors are effectively Colors //* Note that constants.Colors does still appear to exist on newer versions despite Discord not internally using it - what the fuck? -export const rawColors = (constants.Colors ?? colorModule?.default?.unsafe_rawColors ?? colorModule?.RawColor); \ No newline at end of file +export const rawColors = (constants.Colors ?? colorModule?.unsafe_rawColors); \ No newline at end of file diff --git a/src/ui/components/InputAlert.tsx b/src/ui/components/InputAlert.tsx index 2a07614..3bc7f6e 100644 --- a/src/ui/components/InputAlert.tsx +++ b/src/ui/components/InputAlert.tsx @@ -3,7 +3,6 @@ import { Forms, Alert } from "@ui/components"; import { InputAlertProps } from "@types"; const { FormInput } = Forms; - const Alerts = findByProps("openLazy", "close"); export default function InputAlert({ title, confirmText, confirmColor, onConfirm, cancelText, placeholder, initialValue = "" }: InputAlertProps) { diff --git a/src/ui/fixTheme.ts b/src/ui/fixTheme.ts index ef6391a..4e42589 100644 --- a/src/ui/fixTheme.ts +++ b/src/ui/fixTheme.ts @@ -1,8 +1,8 @@ // Based on https://github.com/Aliucord/AliucordRN/blob/main/src/ui/patchTheme.ts // Literally could not figure this out, many thanks -import { findByProps, findByStoreName } from "@metro/filters"; import { FluxDispatcher } from "@metro/common"; +import { findByProps, findByStoreName } from "@metro/filters"; import logger from "@lib/logger"; // TODO: Move these to common modules? diff --git a/src/ui/settings/components/InstallPluginButton.tsx b/src/ui/settings/components/InstallPluginButton.tsx index 1660092..b27d285 100644 --- a/src/ui/settings/components/InstallPluginButton.tsx +++ b/src/ui/settings/components/InstallPluginButton.tsx @@ -1,9 +1,9 @@ -import { HTTP_REGEX } from "@/lib/constants"; -import { semanticColors } from "@ui/color"; -import { installPlugin } from "@lib/plugins"; import { clipboard, stylesheet } from "@metro/common"; +import { HTTP_REGEX } from "@lib/constants"; +import { installPlugin } from "@lib/plugins"; import { showInputAlert } from "@ui/alerts"; import { getAssetIDByName } from "@ui/assets"; +import { semanticColors } from "@ui/color"; import { General } from "@ui/components"; const { TouchableOpacity, Image } = General; diff --git a/src/ui/settings/components/PluginCard.tsx b/src/ui/settings/components/PluginCard.tsx index c2caa06..d0f2c2d 100644 --- a/src/ui/settings/components/PluginCard.tsx +++ b/src/ui/settings/components/PluginCard.tsx @@ -1,16 +1,13 @@ +import { ButtonColors, Plugin } from "@types"; import { ReactNative as RN, stylesheet, NavigationNative } from "@metro/common"; -import { findByProps } from "@metro/filters"; import { Forms, General } from "@ui/components"; -import { Plugin } from "@types"; import { getAssetIDByName } from "@ui/assets"; import { showToast } from "@ui/toasts"; +import { showConfirmationAlert } from "@ui/alerts"; import { semanticColors } from "@ui/color"; import { removePlugin, startPlugin, stopPlugin, getSettings } from "@lib/plugins"; import copyText from "@utils/copyText"; -// TODO: Replace with our eventual dialog API -const Dialog = findByProps("show", "openLazy", "close"); - const { FormRow, FormSwitch } = Forms; const { TouchableOpacity, Image } = General; @@ -79,12 +76,12 @@ export default function PluginCard({ plugin, index }: PluginCardProps) { trailing={ Dialog.show({ + onPress={() => showConfirmationAlert({ title: "Wait!", - body: `Are you sure you wish to delete ${plugin.manifest.name}?`, + content: `Are you sure you wish to delete ${plugin.manifest.name}?`, confirmText: "Delete", cancelText: "Cancel", - confirmColor: "red", + confirmColor: ButtonColors.RED, onConfirm: () => { try { removePlugin(plugin.id); diff --git a/src/ui/settings/index.tsx b/src/ui/settings/index.tsx index 16714a3..0a556d2 100644 --- a/src/ui/settings/index.tsx +++ b/src/ui/settings/index.tsx @@ -4,11 +4,11 @@ import { after } from "@lib/patcher"; import findInReactTree from "@utils/findInReactTree"; import ErrorBoundary from "@ui/components/ErrorBoundary"; import SettingsSection from "@ui/settings/components/SettingsSection"; +import InstallPluginButton from "@ui/settings/components/InstallPluginButton"; import General from "@ui/settings/pages/General"; import Plugins from "@ui/settings/pages/Plugins"; import Developer from "@ui/settings/pages/Developer"; import AssetBrowser from "@ui/settings/pages/AssetBrowser"; -import InstallPluginButton from "@ui/settings/components/InstallPluginButton"; const screensModule = findByDisplayName("getScreens", false); const settingsModule = findByDisplayName("UserSettingsOverviewWrapper", false); diff --git a/src/ui/settings/pages/AssetBrowser.tsx b/src/ui/settings/pages/AssetBrowser.tsx index 7508fdd..c621ccd 100644 --- a/src/ui/settings/pages/AssetBrowser.tsx +++ b/src/ui/settings/pages/AssetBrowser.tsx @@ -1,6 +1,6 @@ import { ReactNative as RN, stylesheet } from "@metro/common"; -import { Forms, Search } from "@ui/components"; import { all } from "@ui/assets"; +import { Forms, Search } from "@ui/components"; import ErrorBoundary from "@ui/components/ErrorBoundary"; import AssetDisplay from "@ui/settings/components/AssetDisplay"; diff --git a/src/ui/settings/pages/Developer.tsx b/src/ui/settings/pages/Developer.tsx index b8f688f..618df83 100644 --- a/src/ui/settings/pages/Developer.tsx +++ b/src/ui/settings/pages/Developer.tsx @@ -1,11 +1,9 @@ import { ReactNative as RN, NavigationNative } from "@metro/common"; import { Forms } from "@ui/components"; import { getAssetIDByName } from "@ui/assets"; -import { showToast } from "@ui/toasts"; import { connectToDebugger } from "@lib/debug"; import { useProxy } from "@lib/storage"; import settings, { loaderConfig } from "@lib/settings"; -import logger from "@lib/logger"; import ErrorBoundary from "@ui/components/ErrorBoundary"; const { FormSection, FormRow, FormSwitchRow, FormInput, FormDivider } = Forms; @@ -37,18 +35,10 @@ export default function Developer() { } - onPress={() => { - try { - window.__vendetta_rdc?.connectToDevTools({ - host: settings.debuggerUrl.split(":")?.[0], - resolveRNStyle: RN.StyleSheet.flatten, - }); - } catch (e) { - // TODO: Check if this ever actually catches anything - logger.error("Failed to connect to React DevTools!", e); - showToast("Failed to connect to React DevTools!", getAssetIDByName("Small")); - } - }} + onPress={() => window.__vendetta_rdc?.connectToDevTools({ + host: settings.debuggerUrl.split(":")?.[0], + resolveRNStyle: RN.StyleSheet.flatten, + })} /> } diff --git a/src/ui/settings/pages/General.tsx b/src/ui/settings/pages/General.tsx index 354dc38..a6b19bd 100644 --- a/src/ui/settings/pages/General.tsx +++ b/src/ui/settings/pages/General.tsx @@ -1,7 +1,7 @@ import { ReactNative as RN, url, invites } from "@metro/common"; -import { DISCORD_SERVER, GITHUB } from "@lib/constants"; import { getAssetIDByName } from "@ui/assets"; import { Forms, Summary } from "@ui/components"; +import { DISCORD_SERVER, GITHUB } from "@lib/constants"; import { getDebugInfo } from "@lib/debug"; import { useProxy } from "@lib/storage"; import settings from "@lib/settings"; diff --git a/src/ui/toasts.ts b/src/ui/toasts.ts index fa6435b..7c8671c 100644 --- a/src/ui/toasts.ts +++ b/src/ui/toasts.ts @@ -1,8 +1,6 @@ import { toasts } from "@metro/common"; -export function showToast(content: string, asset: number) { - return toasts.open({ - content: content, - source: asset, - }); -} \ No newline at end of file +export const showToast = (content: string, asset: number) => toasts.open({ + content: content, + source: asset, +}); \ No newline at end of file