From 4ec2cfb4a91e5201f51b1c34f9e2b9e68398204c Mon Sep 17 00:00:00 2001 From: Federico <38290480+FedeIlLeone@users.noreply.github.com> Date: Sat, 28 Oct 2023 17:47:17 +0200 Subject: [PATCH 1/2] fix: more common modules --- src/renderer/modules/common/components.ts | 3 ++ src/renderer/modules/common/flux.ts | 66 ++++++++++------------- src/renderer/modules/common/guilds.ts | 24 +++++---- src/renderer/modules/common/index.ts | 2 + src/renderer/modules/common/modal.ts | 2 +- src/renderer/modules/common/toast.ts | 33 +++++++----- 6 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/renderer/modules/common/components.ts b/src/renderer/modules/common/components.ts index 4ae0e3955..6e0bf66e2 100644 --- a/src/renderer/modules/common/components.ts +++ b/src/renderer/modules/common/components.ts @@ -17,12 +17,14 @@ import type { TextAreaType } from "../components/TextArea"; import type { TextInputType } from "../components/TextInput"; import type { OriginalTooltipType } from "../components/Tooltip"; import { waitForProps } from "../webpack"; +import type { CreateToast, ShowToast } from "./toast"; // Expand this as needed interface DiscordComponents { Button: ButtonType; Checkbox: CheckboxType; Clickable: ClickableCompType; + createToast: CreateToast; FormDivider: DividerType; FormItem: FormItemCompType; FormNotice: FormNoticeType; @@ -43,6 +45,7 @@ interface DiscordComponents { ModalRoot: ModalType["ModalRoot"]; RadioGroup: RadioType; Select: SelectCompType; + showToast: ShowToast; Slider: SliderCompType; Spinner: LoaderType; Switch: SwitchType; diff --git a/src/renderer/modules/common/flux.ts b/src/renderer/modules/common/flux.ts index 281d321fb..36810961a 100644 --- a/src/renderer/modules/common/flux.ts +++ b/src/renderer/modules/common/flux.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { filters, getFunctionBySource, waitForModule, waitForProps } from "../webpack"; +import { filters, waitForModule, waitForProps } from "../webpack"; import type { DispatchBand, FluxDispatcher as Dispatcher } from "./fluxDispatcher"; type DispatchToken = string; @@ -187,46 +187,34 @@ const SnapshotStoreClass = await waitForModule( filters.bySource("SnapshotStores"), ); -type useStateFromStores = ( - stores: Store[], - callback: () => T, - deps?: React.DependencyList, - compare?: - | ((a: T, b: T) => boolean) - | (>(a: T, b: T) => boolean), -) => T; -type statesWillNeverBeEqual = (a: T, b: T) => boolean; -type useStateFromStoresArray = ( - stores: Store[], - callback: () => T, - deps?: React.DependencyList, -) => T; -type useStateFromStoresObject = ( - stores: Store[], - callback: () => T, - deps?: React.DependencyList, -) => T; - -const FluxHooksMod = await waitForModule(filters.bySource("useStateFromStores")); - -const useStateFromStores = getFunctionBySource( - FluxHooksMod, - "useStateFromStores", -)!; -const statesWillNeverBeEqual = getFunctionBySource( - FluxHooksMod, - "return!1", -)!; -const useStateFromStoresArray: useStateFromStoresArray = (stores, callback, deps) => - useStateFromStores(stores, callback, deps, _.isEqual); -const useStateFromStoresObject: useStateFromStoresObject = (stores, callback, deps) => - useStateFromStores(stores, callback, deps, _.isEqual); +interface FluxHooks { + useStateFromStores: ( + stores: Store[], + callback: () => T, + deps?: React.DependencyList, + compare?: + | ((a: T, b: T) => boolean) + | (>(a: T, b: T) => boolean), + ) => T; + statesWillNeverBeEqual: (a: T, b: T) => boolean; + useStateFromStoresArray: ( + stores: Store[], + callback: () => T, + deps?: React.DependencyList, + ) => T; + useStateFromStoresObject: ( + stores: Store[], + callback: () => T, + deps?: React.DependencyList, + ) => T; +} +const FluxHooksMod = await waitForProps("useStateFromStores"); const FluxHooks = { - useStateFromStores, - statesWillNeverBeEqual, - useStateFromStoresArray, - useStateFromStoresObject, + useStateFromStores: FluxHooksMod.useStateFromStores, + statesWillNeverBeEqual: FluxHooksMod.statesWillNeverBeEqual, + useStateFromStoresArray: FluxHooksMod.useStateFromStoresArray, + useStateFromStoresObject: FluxHooksMod.useStateFromStoresObject, }; export type Flux = FluxMod & { SnapshotStore: typeof SnapshotStore } & typeof FluxHooks; diff --git a/src/renderer/modules/common/guilds.ts b/src/renderer/modules/common/guilds.ts index d01a40dee..21a33f0b2 100644 --- a/src/renderer/modules/common/guilds.ts +++ b/src/renderer/modules/common/guilds.ts @@ -1,6 +1,7 @@ -import { waitForProps } from "../webpack"; import type { Guild } from "discord-types/general"; import { virtualMerge } from "src/renderer/util"; +import { waitForProps } from "../webpack"; +import type { Store } from "./flux"; interface State { selectedGuildTimestampMillis: Record; @@ -27,17 +28,20 @@ export interface GuildStore { export type Guilds = SelectedGuildStore & GuildStore; -const guilds: Guilds = { - ...(await waitForProps("getGuild", "getGuilds").then(Object.getPrototypeOf)), - ...(await waitForProps("getGuildId", "getLastSelectedGuildId").then( - Object.getPrototypeOf, - )), -}; +const GuildStore = await waitForProps("getGuild", "getGuildIds"); +const SelectedGuildStore = await waitForProps( + "getGuildId", + "getLastSelectedGuildId", +); export function getCurrentGuild(): Guild | undefined { - const guildId = guilds.getGuildId(); + const guildId = SelectedGuildStore.getGuildId(); if (!guildId) return undefined; - return guilds.getGuild(guildId); + return GuildStore.getGuild(guildId); } -export default virtualMerge(guilds, { getCurrentGuild }); +export default virtualMerge( + Object.getPrototypeOf(GuildStore) as GuildStore, + Object.getPrototypeOf(SelectedGuildStore) as SelectedGuildStore, + { getCurrentGuild }, +); diff --git a/src/renderer/modules/common/index.ts b/src/renderer/modules/common/index.ts index e0d59c9c0..c23d0ccd9 100644 --- a/src/renderer/modules/common/index.ts +++ b/src/renderer/modules/common/index.ts @@ -53,6 +53,8 @@ export type { API }; export let api: API; importTimeout("api", import("./api"), (mod) => (api = mod.default)); +import * as Components from "./components"; +export type { Components }; export let components: typeof import("./components").default; importTimeout("components", import("./components"), (mod) => (components = mod.default)); diff --git a/src/renderer/modules/common/modal.ts b/src/renderer/modules/common/modal.ts index 1b0392b57..58394d17d 100644 --- a/src/renderer/modules/common/modal.ts +++ b/src/renderer/modules/common/modal.ts @@ -66,7 +66,7 @@ export type Modal = { const mod = await waitForModule(filters.bySource("onCloseRequest:null!=")); const alertMod = await waitForProps("show", "close"); -const classes = getBySource("().justifyStart")!; +const classes = getBySource(".justifyStart")!; export default { openModal: getFunctionBySource(mod, "onCloseRequest:null!=")!, diff --git a/src/renderer/modules/common/toast.ts b/src/renderer/modules/common/toast.ts index 660221ebe..3bb98e049 100644 --- a/src/renderer/modules/common/toast.ts +++ b/src/renderer/modules/common/toast.ts @@ -1,4 +1,5 @@ -import { filters, getFunctionBySource, waitForModule } from "../webpack"; +import type React from "react"; +import { components } from "."; const Kind = { MESSAGE: 0, @@ -19,11 +20,26 @@ interface ToastOptions { component?: React.ReactElement; } +interface ToastProps { + message: string | React.ReactElement | null; + id: string; + type: (typeof Kind)[keyof typeof Kind]; + options: ToastOptions; +} + +export type CreateToast = ( + content: string | React.ReactElement | null, + kind?: (typeof Kind)[keyof typeof Kind], + opts?: ToastOptions, +) => ToastProps; + +export type ShowToast = (props: ToastProps) => void; + type ToastFn = ( content: string | React.ReactElement | null, kind?: (typeof Kind)[keyof typeof Kind], opts?: ToastOptions, -) => unknown; +) => void; export interface Toast { toast: ToastFn; @@ -31,18 +47,9 @@ export interface Toast { Position: typeof Position; } -const mod = await waitForModule(filters.bySource("queuedToasts")); -const fn = getFunctionBySource<(props: ReturnType) => void>(mod, "queuedToasts).concat")!; - -const propGenMod = await waitForModule(filters.bySource(/case (\w+\.){1,2}FAILURE/)); -const propGenFn = getFunctionBySource( - propGenMod, - /options:{position:\w+,component:\w+,duration:\w+}/, -)!; - const toast: ToastFn = (content, kind = Kind.SUCCESS, opts = undefined) => { - const props = propGenFn(content, kind, opts); - fn(props); + const props = components.createToast(content, kind, opts); + components.showToast(props); }; export default { From 6e7c7b1bb035c8eb3d353cca1bc9bf803f76989d Mon Sep 17 00:00:00 2001 From: Federico <38290480+FedeIlLeone@users.noreply.github.com> Date: Sat, 28 Oct 2023 17:47:35 +0200 Subject: [PATCH 2/2] fix(util): openExternal undefined --- src/renderer/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/util.ts b/src/renderer/util.ts index 34f9a8312..1cb418c82 100644 --- a/src/renderer/util.ts +++ b/src/renderer/util.ts @@ -172,7 +172,7 @@ export async function goToOrJoinServer(invite: string): Promise { } export async function openExternal(url: string): Promise { - const mod = getBySource<(url: string) => Promise>(/href=\w;\w\.target="_blank"/); + const mod = getBySource<(url: string) => Promise>(/href=\w,\w\.target="_blank"/); if (!mod) { throw new Error("Could not find openExternal"); }