diff options
Diffstat (limited to 'src/webpack/common')
-rw-r--r-- | src/webpack/common/components.ts | 3 | ||||
-rw-r--r-- | src/webpack/common/internal.tsx | 6 | ||||
-rw-r--r-- | src/webpack/common/react.ts | 2 | ||||
-rw-r--r-- | src/webpack/common/stores.ts | 77 | ||||
-rw-r--r-- | src/webpack/common/types/components.d.ts | 6 | ||||
-rw-r--r-- | src/webpack/common/types/index.d.ts | 1 | ||||
-rw-r--r-- | src/webpack/common/types/stores.d.ts | 40 | ||||
-rw-r--r-- | src/webpack/common/types/utils.d.ts | 14 | ||||
-rw-r--r-- | src/webpack/common/utils.ts | 1 |
9 files changed, 109 insertions, 41 deletions
diff --git a/src/webpack/common/components.ts b/src/webpack/common/components.ts index be585c3..27d103f 100644 --- a/src/webpack/common/components.ts +++ b/src/webpack/common/components.ts @@ -49,5 +49,8 @@ export const Slider = waitForComponent<t.Slider>("Slider", filters.byCode("close export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]); export const ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent") as Record<string, string>; +/** + * @deprecated Use @utils/margins instead + */ export const Margins: t.Margins = findByPropsLazy("marginTop20"); export const ButtonLooks: t.ButtonLooks = findByPropsLazy("BLANK", "FILLED", "INVERTED"); diff --git a/src/webpack/common/internal.tsx b/src/webpack/common/internal.tsx index df768f7..e2f42d8 100644 --- a/src/webpack/common/internal.tsx +++ b/src/webpack/common/internal.tsx @@ -19,7 +19,7 @@ import { LazyComponent } from "@utils/misc"; // eslint-disable-next-line path-alias/no-relative -import { FilterFn, waitFor } from "../webpack"; +import { FilterFn, filters, waitFor } from "../webpack"; export function waitForComponent<T extends React.ComponentType<any> = React.ComponentType<any> & Record<string, any>>(name: string, filter: FilterFn | string | string[]): T { let myValue: T = function () { @@ -34,3 +34,7 @@ export function waitForComponent<T extends React.ComponentType<any> = React.Comp return lazyComponent; } + +export function waitForStore(name: string, cb: (v: any) => void) { + waitFor(filters.byStoreName(name), cb); +} diff --git a/src/webpack/common/react.ts b/src/webpack/common/react.ts index 455f39b..d73a3df 100644 --- a/src/webpack/common/react.ts +++ b/src/webpack/common/react.ts @@ -25,7 +25,7 @@ export let useEffect: typeof React.useEffect; export let useMemo: typeof React.useMemo; export let useRef: typeof React.useRef; -export const ReactDOM: typeof import("react-dom") = findByPropsLazy("createPortal", "render"); +export const ReactDOM: typeof import("react-dom") & typeof import("react-dom/client") = findByPropsLazy("createPortal", "render"); waitFor("useState", m => { React = m; diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index bcd26b1..0bd9e87 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -19,36 +19,71 @@ import type * as Stores from "discord-types/stores"; // eslint-disable-next-line path-alias/no-relative -import { filters, findByPropsLazy, mapMangledModuleLazy, waitFor } from "../webpack"; +import { filters, findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "../webpack"; +import { waitForStore } from "./internal"; +import * as t from "./types/stores"; -export const MessageStore = findByPropsLazy("getRawMessages") as Omit<Stores.MessageStore, "getMessages"> & { +export const Flux: t.Flux = findByPropsLazy("connectStores"); + +type GenericStore = t.FluxStore & Record<string, any>; + +export let MessageStore: Omit<Stores.MessageStore, "getMessages"> & { getMessages(chanId: string): any; }; -export const PermissionStore = findByPropsLazy("can", "getGuildPermissions"); + +// this is not actually a FluxStore export const PrivateChannelsStore = findByPropsLazy("openPrivateChannel"); -export const GuildChannelStore = findByPropsLazy("getChannels"); -export const ReadStateStore = findByPropsLazy("lastMessageId"); -export const PresenceStore = findByPropsLazy("setCurrentUserOnConnectionOpen"); - -export let GuildStore: Stores.GuildStore; -export let UserStore: Stores.UserStore; -export let SelectedChannelStore: Stores.SelectedChannelStore; -export let SelectedGuildStore: any; -export let ChannelStore: Stores.ChannelStore; -export let GuildMemberStore: Stores.GuildMemberStore; -export let RelationshipStore: Stores.RelationshipStore & { +export let PermissionStore: GenericStore; +export let GuildChannelStore: GenericStore; +export let ReadStateStore: GenericStore; +export let PresenceStore: GenericStore; + +export let GuildStore: Stores.GuildStore & t.FluxStore; +export let UserStore: Stores.UserStore & t.FluxStore; +export let SelectedChannelStore: Stores.SelectedChannelStore & t.FluxStore; +export let SelectedGuildStore: t.FluxStore & Record<string, any>; +export let ChannelStore: Stores.ChannelStore & t.FluxStore; +export let GuildMemberStore: Stores.GuildMemberStore & t.FluxStore; +export let RelationshipStore: Stores.RelationshipStore & t.FluxStore & { /** Get the date (as a string) that the relationship was created */ getSince(userId: string): string; }; +export let WindowStore: t.WindowStore; + export const MaskedLinkStore = mapMangledModuleLazy('"MaskedLinkStore"', { openUntrustedLink: filters.byCode(".apply(this,arguments)") }); -waitFor(["getCurrentUser", "initialize"], m => UserStore = m); -waitFor("getSortedPrivateChannels", m => ChannelStore = m); -waitFor("getCurrentlySelectedChannelId", m => SelectedChannelStore = m); -waitFor("getLastSelectedGuildId", m => SelectedGuildStore = m); -waitFor("getGuildCount", m => GuildStore = m); -waitFor(["getMember", "initialize"], m => GuildMemberStore = m); -waitFor("getRelationshipType", m => RelationshipStore = m); +/** + * React hook that returns stateful data for one or more stores + * You might need a custom comparator (4th argument) if your store data is an object + * + * @param stores The stores to listen to + * @param mapper A function that returns the data you need + * @param idk some thing, idk just pass null + * @param isEqual A custom comparator for the data returned by mapper + * + * @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id); + */ +export const useStateFromStores: <T>( + stores: t.FluxStore[], + mapper: () => T, + idk?: any, + isEqual?: (old: T, newer: T) => boolean +) => T + = findByCodeLazy("useStateFromStores"); + +waitForStore("UserStore", s => UserStore = s); +waitForStore("ChannelStore", m => ChannelStore = m); +waitForStore("SelectedChannelStore", m => SelectedChannelStore = m); +waitForStore("SelectedGuildStore", m => SelectedGuildStore = m); +waitForStore("GuildStore", m => GuildStore = m); +waitForStore("GuildMemberStore", m => GuildMemberStore = m); +waitForStore("RelationshipStore", m => RelationshipStore = m); +waitForStore("PermissionStore", m => PermissionStore = m); +waitForStore("PresenceStore", m => PresenceStore = m); +waitForStore("ReadStateStore", m => ReadStateStore = m); +waitForStore("GuildChannelStore", m => GuildChannelStore = m); +waitForStore("MessageStore", m => MessageStore = m); +waitForStore("WindowStore", m => WindowStore = m); diff --git a/src/webpack/common/types/components.d.ts b/src/webpack/common/types/components.d.ts index 3f76c22..9cd01de 100644 --- a/src/webpack/common/types/components.d.ts +++ b/src/webpack/common/types/components.d.ts @@ -215,9 +215,9 @@ export type Select = ComponentType<PropsWithChildren<{ closeOnSelect?: boolean; hideIcon?: boolean; - select?(value: any): void; - isSelected?(value: any): boolean; - serialize?(value: any): string; + select(value: any): void; + isSelected(value: any): boolean; + serialize(value: any): string; clear?(): void; maxVisibleItems?: number; diff --git a/src/webpack/common/types/index.d.ts b/src/webpack/common/types/index.d.ts index 9d6c295..af4b5e1 100644 --- a/src/webpack/common/types/index.d.ts +++ b/src/webpack/common/types/index.d.ts @@ -19,5 +19,6 @@ export * from "./components"; export * from "./fluxEvents"; export * from "./menu"; +export * from "./stores"; export * from "./utils"; diff --git a/src/webpack/common/types/stores.d.ts b/src/webpack/common/types/stores.d.ts new file mode 100644 index 0000000..6af5b27 --- /dev/null +++ b/src/webpack/common/types/stores.d.ts @@ -0,0 +1,40 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +import { FluxDispatcher, FluxEvents } from "./utils"; + +export class FluxStore { + constructor(dispatcher: FluxDispatcher, eventHandlers?: Partial<Record<FluxEvents, (data: any) => void>>); + + emitChange(): void; + getDispatchToken(): string; + getName(): string; + initialize(): void; + initializeIfNeeded(): void; + __getLocalVars(): Record<string, any>; +} + +export interface Flux { + Store: typeof FluxStore; +} + +export class WindowStore extends FluxStore { + isElementFullScreen(): boolean; + isFocused(): boolean; + windowSize(): Record<"width" | "height", number>; +} diff --git a/src/webpack/common/types/utils.d.ts b/src/webpack/common/types/utils.d.ts index 7222be4..0e2a6ca 100644 --- a/src/webpack/common/types/utils.d.ts +++ b/src/webpack/common/types/utils.d.ts @@ -31,20 +31,6 @@ export interface FluxDispatcher { unsubscribe(event: FluxEvents, callback: (data: any) => void): void; } -declare class FluxStore { - constructor(dispatcher: FluxDispatcher, eventHandlers?: Partial<Record<FluxEvents, (data: any) => void>>); - - emitChange(): void; - getDispatchToken(): string; - getName(): string; - initialize(): void; - initializeIfNeeded(): void; -} - -export interface Flux { - Store: typeof FluxStore; -} - export type Parser = Record< | "parse" | "parseTopic" diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index daac207..b53c340 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -23,7 +23,6 @@ import { _resolveReady,filters, findByCodeLazy, findByPropsLazy, mapMangledModul import type * as t from "./types/utils"; export let FluxDispatcher: t.FluxDispatcher; -export const Flux: t.Flux = findByPropsLazy("connectStores"); export const RestAPI: t.RestAPI = findByPropsLazy("getAPIBaseURL", "get"); export const moment: typeof import("moment") = findByPropsLazy("parseTwoDigitYear"); |