mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-16 09:57:08 -04:00
parent
ae730e8398
commit
5625d63e46
22 changed files with 945 additions and 192 deletions
|
@ -1,15 +1,6 @@
|
|||
import { filters } from "../webpack";
|
||||
import { lazyWebpack } from "./misc";
|
||||
import { mapMangledModuleLazy } from "../webpack/webpack";
|
||||
|
||||
const ModalRoot = lazyWebpack(filters.byCode("headerIdIsManaged:"));
|
||||
const Modals = mapMangledModuleLazy("onCloseRequest:null!=", {
|
||||
openModal: filters.byCode("onCloseRequest:null!="),
|
||||
closeModal: filters.byCode("onCloseCallback&&")
|
||||
});
|
||||
|
||||
let modalId = 1337;
|
||||
|
||||
export enum ModalSize {
|
||||
SMALL = "small",
|
||||
MEDIUM = "medium",
|
||||
|
@ -17,26 +8,64 @@ export enum ModalSize {
|
|||
DYNAMIC = "dynamic",
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a modal
|
||||
* @param Component The component to render in the modal
|
||||
* @returns The key of this modal. This can be used to close the modal later with closeModal
|
||||
*/
|
||||
export function openModal(Component: React.ComponentType, modalProps: Record<string, any>) {
|
||||
let key = `Vencord${modalId++}`;
|
||||
Modals.openModal(props => (
|
||||
<ModalRoot {...props} {...modalProps}>
|
||||
<Component />
|
||||
</ModalRoot>
|
||||
), { modalKey: key });
|
||||
|
||||
return key;
|
||||
enum ModalTransitionState {
|
||||
ENTERING,
|
||||
ENTERED,
|
||||
EXITING,
|
||||
EXITED,
|
||||
HIDDEN,
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a modal by key. The id you need for this is returned by openModal.
|
||||
* @param key The key of the modal to close
|
||||
*/
|
||||
export function closeModal(key: string) {
|
||||
Modals.closeModal(key);
|
||||
export interface ModalProps {
|
||||
transitionState: ModalTransitionState;
|
||||
onClose(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ModalOptions {
|
||||
modalKey?: string;
|
||||
onCloseRequest?: (() => void);
|
||||
onCloseCallback?: (() => void);
|
||||
}
|
||||
|
||||
interface ModalRootProps {
|
||||
transitionState: ModalTransitionState;
|
||||
children: React.ReactNode;
|
||||
size?: ModalSize;
|
||||
role?: "alertdialog" | "dialog";
|
||||
className?: string;
|
||||
onAnimationEnd?(): string;
|
||||
}
|
||||
|
||||
type RenderFunction = (props: ModalProps) => React.ReactNode;
|
||||
|
||||
export const Modals = mapMangledModuleLazy(".onAnimationEnd,", {
|
||||
ModalRoot: filters.byCode("headerIdIsManaged:"),
|
||||
ModalHeader: filters.byCode("children", "separator", "wrap", "NO_WRAP", "grow", "shrink", "id", "header"),
|
||||
ModalContent: filters.byCode("scrollerRef", "content", "className", "children"),
|
||||
ModalFooter: filters.byCode("HORIZONTAL_REVERSE", "START", "STRETCH", "NO_WRAP", "footerSeparator"),
|
||||
ModalCloseButton: filters.byCode("closeWithCircleBackground", "hideOnFullscreen"),
|
||||
});
|
||||
|
||||
export const ModalRoot = (props: ModalRootProps) => <Modals.ModalRoot {...props} />;
|
||||
export const ModalHeader = (props: any) => <Modals.ModalHeader {...props} />;
|
||||
export const ModalContent = (props: any) => <Modals.ModalContent {...props} />;
|
||||
export const ModalFooter = (props: any) => <Modals.ModalFooter {...props} />;
|
||||
export const ModalCloseButton = (props: any) => <Modals.ModalCloseButton {...props} />;
|
||||
|
||||
const ModalAPI = mapMangledModuleLazy("onCloseRequest:null!=", {
|
||||
openModal: filters.byCode("onCloseRequest:null!="),
|
||||
closeModal: filters.byCode("onCloseCallback&&"),
|
||||
openModalLazy: m => m?.length === 1 && filters.byCode(".apply(this,arguments)")(m),
|
||||
});
|
||||
|
||||
export function openModalLazy(render: () => Promise<RenderFunction>, options?: ModalOptions & { contextKey?: string; }): Promise<string> {
|
||||
return ModalAPI.openModalLazy(render, options);
|
||||
}
|
||||
|
||||
export function openModal(render: RenderFunction, options?: ModalOptions, contextKey?: string): string {
|
||||
return ModalAPI.openModal(render, options, contextKey);
|
||||
}
|
||||
|
||||
export function closeModal(modalKey: string, contextKey?: string): void {
|
||||
return ModalAPI.closeModal(modalKey, contextKey);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ export interface Patch {
|
|||
find: string;
|
||||
replacement: PatchReplacement | PatchReplacement[];
|
||||
all?: boolean;
|
||||
predicate?(): boolean;
|
||||
}
|
||||
|
||||
export interface PluginAuthor {
|
||||
|
@ -34,13 +35,101 @@ interface PluginDef {
|
|||
start?(): void;
|
||||
stop?(): void;
|
||||
patches?: Omit<Patch, "plugin">[];
|
||||
/**
|
||||
* List of commands. If you specify these, you must add CommandsAPI to dependencies
|
||||
*/
|
||||
commands?: Command[];
|
||||
/**
|
||||
* A list of other plugins that your plugin depends on.
|
||||
* These will automatically be enabled and loaded before your plugin
|
||||
* Common examples are CommandsAPI, MessageEventsAPI...
|
||||
*/
|
||||
dependencies?: string[],
|
||||
/**
|
||||
* Whether this plugin is required and forcefully enabled
|
||||
*/
|
||||
required?: boolean;
|
||||
/**
|
||||
* Set this if your plugin only works on Browser or Desktop, not both
|
||||
*/
|
||||
target?: "WEB" | "DESKTOP" | "BOTH";
|
||||
/**
|
||||
* Optionally provide settings that the user can configure in the Plugins tab of settings.
|
||||
*/
|
||||
options?: Record<string, PluginOptionsItem>;
|
||||
/**
|
||||
* Allows you to specify a custom Component that will be rendered in your
|
||||
* plugin's settings page
|
||||
*/
|
||||
settingsAboutComponent?: React.ComponentType;
|
||||
}
|
||||
|
||||
export enum OptionType {
|
||||
STRING,
|
||||
NUMBER,
|
||||
BIGINT,
|
||||
BOOLEAN,
|
||||
SELECT,
|
||||
}
|
||||
|
||||
export type PluginOptionsItem =
|
||||
| PluginOptionString
|
||||
| PluginOptionNumber
|
||||
| PluginOptionBoolean
|
||||
| PluginOptionSelect;
|
||||
|
||||
export interface PluginOptionBase {
|
||||
description: string;
|
||||
placeholder?: string;
|
||||
onChange?(newValue: any): void;
|
||||
disabled?(): boolean;
|
||||
restartNeeded?: boolean;
|
||||
componentProps?: Record<string, any>;
|
||||
/**
|
||||
* Set this if the setting only works on Browser or Desktop, not both
|
||||
*/
|
||||
target?: "WEB" | "DESKTOP" | "BOTH";
|
||||
}
|
||||
|
||||
export interface PluginOptionString extends PluginOptionBase {
|
||||
type: OptionType.STRING;
|
||||
/**
|
||||
* Prevents the user from saving settings if this is false or a string
|
||||
*/
|
||||
isValid?(value: string): boolean | string;
|
||||
default?: string;
|
||||
}
|
||||
|
||||
export interface PluginOptionNumber extends PluginOptionBase {
|
||||
type: OptionType.NUMBER | OptionType.BIGINT;
|
||||
/**
|
||||
* Prevents the user from saving settings if this is false or a string
|
||||
*/
|
||||
isValid?(value: number | BigInt): boolean | string;
|
||||
default?: number;
|
||||
}
|
||||
|
||||
export interface PluginOptionBoolean extends PluginOptionBase {
|
||||
type: OptionType.BOOLEAN;
|
||||
/**
|
||||
* Prevents the user from saving settings if this is false or a string
|
||||
*/
|
||||
isValid?(value: boolean): boolean | string;
|
||||
default?: boolean;
|
||||
}
|
||||
|
||||
export interface PluginOptionSelect extends PluginOptionBase {
|
||||
type: OptionType.SELECT;
|
||||
/**
|
||||
* Prevents the user from saving settings if this is false or a string
|
||||
*/
|
||||
isValid?(value: PluginOptionSelectOption): boolean | string;
|
||||
options: PluginOptionSelectOption[];
|
||||
}
|
||||
export interface PluginOptionSelectOption {
|
||||
label: string;
|
||||
value: string | number | boolean;
|
||||
default?: boolean;
|
||||
}
|
||||
|
||||
export type IpcRes<V = any> = { ok: true; value: V; } | { ok: false, error: any; };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue