mirror of
https://github.com/Vendicated/Vencord.git
synced 2025-01-10 09:56:24 +00:00
yes
This commit is contained in:
parent
126f2df811
commit
15b7982228
6 changed files with 29 additions and 39 deletions
1
src/globals.d.ts
vendored
1
src/globals.d.ts
vendored
|
@ -20,6 +20,7 @@ import { LoDashStatic } from "lodash";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
type AnyRecord = Record<PropertyKey, any>;
|
type AnyRecord = Record<PropertyKey, any>;
|
||||||
|
type AnyComponentType<P extends AnyRecord> = React.ComponentType<P> & AnyRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This exists only at build time, so references to it in patches should insert it
|
* This exists only at build time, so references to it in patches should insert it
|
||||||
|
|
|
@ -19,7 +19,7 @@ type DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTM
|
||||||
export let DecorationGridItem: DecorationGridItemComponent = NoopComponent;
|
export let DecorationGridItem: DecorationGridItemComponent = NoopComponent;
|
||||||
export const setDecorationGridItem = v => DecorationGridItem = v;
|
export const setDecorationGridItem = v => DecorationGridItem = v;
|
||||||
|
|
||||||
export const AvatarDecorationModalPreview = findComponentByCode<any>(".shopPreviewBanner", component => React.memo(component));
|
export const AvatarDecorationModalPreview = findComponentByCode(".shopPreviewBanner", component => React.memo(component));
|
||||||
|
|
||||||
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
|
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
|
||||||
avatarDecoration: AvatarDecoration;
|
avatarDecoration: AvatarDecoration;
|
||||||
|
|
|
@ -17,7 +17,7 @@ export function makeLazy<T>(factory: () => T, attempts = 5, { isIndirect = false
|
||||||
let tries = 0;
|
let tries = 0;
|
||||||
let cache: T;
|
let cache: T;
|
||||||
|
|
||||||
const getter = () => {
|
const getter: LazyFunction<T> = function () {
|
||||||
if (!cache && attempts > tries) {
|
if (!cache && attempts > tries) {
|
||||||
tries++;
|
tries++;
|
||||||
cache = factory();
|
cache = factory();
|
||||||
|
@ -30,7 +30,6 @@ export function makeLazy<T>(factory: () => T, attempts = 5, { isIndirect = false
|
||||||
};
|
};
|
||||||
|
|
||||||
getter.$$vencordLazyFailed = () => tries === attempts;
|
getter.$$vencordLazyFailed = () => tries === attempts;
|
||||||
|
|
||||||
return getter;
|
return getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,17 +68,11 @@ const handler: ProxyHandler<any> = {
|
||||||
*
|
*
|
||||||
* @param factory Factory returning the result
|
* @param factory Factory returning the result
|
||||||
* @param attempts How many times to try to evaluate the factory before giving up
|
* @param attempts How many times to try to evaluate the factory before giving up
|
||||||
* @param errMsg The error message to throw when the factory fails
|
* @param err The error message to throw when the factory fails
|
||||||
* @param primitiveErrMsg The error message to throw when factory result is a primitive
|
* @param primitiveErr The error message to throw when factory result is a primitive
|
||||||
* @returns Result of factory function
|
* @returns Result of factory function
|
||||||
*/
|
*/
|
||||||
export function proxyLazy<T = any>(
|
export function proxyLazy<T = any>(factory: () => T, attempts = 5, err: string | (() => string) = `proxyLazy factory failed:\n${factory}`, primitiveErr = "proxyLazy called on a primitive value.", isChild = false): T {
|
||||||
factory: () => T,
|
|
||||||
attempts = 5,
|
|
||||||
errMsg: string | (() => string) = `proxyLazy factory failed:\n${factory}`,
|
|
||||||
primitiveErrMsg = "proxyLazy called on a primitive value.",
|
|
||||||
isChild = false
|
|
||||||
): T {
|
|
||||||
const get = makeLazy(factory, attempts, { isIndirect: true });
|
const get = makeLazy(factory, attempts, { isIndirect: true });
|
||||||
|
|
||||||
let isSameTick = true;
|
let isSameTick = true;
|
||||||
|
@ -93,7 +86,7 @@ export function proxyLazy<T = any>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proxyDummy[SYM_LAZY_CACHED]) {
|
if (!proxyDummy[SYM_LAZY_CACHED]) {
|
||||||
throw new Error(typeof errMsg === "string" ? errMsg : errMsg());
|
throw new Error(typeof err === "string" ? err : err());
|
||||||
} else {
|
} else {
|
||||||
if (typeof proxyDummy[SYM_LAZY_CACHED] === "function") {
|
if (typeof proxyDummy[SYM_LAZY_CACHED] === "function") {
|
||||||
proxy.toString = proxyDummy[SYM_LAZY_CACHED].toString.bind(proxyDummy[SYM_LAZY_CACHED]);
|
proxy.toString = proxyDummy[SYM_LAZY_CACHED].toString.bind(proxyDummy[SYM_LAZY_CACHED]);
|
||||||
|
@ -129,8 +122,8 @@ export function proxyLazy<T = any>(
|
||||||
return Reflect.get(lazyTarget, p, lazyTarget);
|
return Reflect.get(lazyTarget, p, lazyTarget);
|
||||||
},
|
},
|
||||||
attempts,
|
attempts,
|
||||||
errMsg,
|
err,
|
||||||
primitiveErrMsg,
|
primitiveErr,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +133,7 @@ export function proxyLazy<T = any>(
|
||||||
return Reflect.get(lazyTarget, p, lazyTarget);
|
return Reflect.get(lazyTarget, p, lazyTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(primitiveErrMsg);
|
throw new Error(primitiveErr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { makeLazy } from "./lazy";
|
||||||
export const SYM_LAZY_COMPONENT_INNER = Symbol.for("vencord.lazyComponent.inner");
|
export const SYM_LAZY_COMPONENT_INNER = Symbol.for("vencord.lazyComponent.inner");
|
||||||
|
|
||||||
export type LazyComponentType<P extends AnyRecord> = React.FunctionComponent<P> & AnyRecord & {
|
export type LazyComponentType<P extends AnyRecord> = React.FunctionComponent<P> & AnyRecord & {
|
||||||
[SYM_LAZY_COMPONENT_INNER]: () => LazyComponentType<P> | null;
|
[SYM_LAZY_COMPONENT_INNER]: () => AnyComponentType<P> | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,10 +19,10 @@ export type LazyComponentType<P extends AnyRecord> = React.FunctionComponent<P>
|
||||||
* @param attempts How many times to try to get the component before giving up
|
* @param attempts How many times to try to get the component before giving up
|
||||||
* @returns Result of factory function
|
* @returns Result of factory function
|
||||||
*/
|
*/
|
||||||
export function LazyComponent<P extends AnyRecord>(factory: () => any, attempts = 5, err: string | (() => string) = `LazyComponent factory failed:\n${factory}`): LazyComponentType<P> {
|
export function LazyComponent<P extends AnyRecord>(factory: () => AnyComponentType<P>, attempts = 5, err: string | (() => string) = `LazyComponent factory failed:\n${factory}`): LazyComponentType<P> {
|
||||||
const get = makeLazy(factory, attempts, { isIndirect: true });
|
const get = makeLazy(factory, attempts, { isIndirect: true });
|
||||||
|
|
||||||
let InnerComponent = null as LazyComponentType<P> | null;
|
let InnerComponent = null as AnyComponentType<P> | null;
|
||||||
|
|
||||||
let lazyFailedLogged = false;
|
let lazyFailedLogged = false;
|
||||||
const LazyComponent: LazyComponentType<P> = function (props) {
|
const LazyComponent: LazyComponentType<P> = function (props) {
|
||||||
|
|
|
@ -42,22 +42,18 @@ const handler: ProxyHandler<any> = {
|
||||||
* IMPORTANT:
|
* IMPORTANT:
|
||||||
* Destructuring at top level is not supported for proxyInner.
|
* Destructuring at top level is not supported for proxyInner.
|
||||||
*
|
*
|
||||||
* @param errMsg The error message to throw when the inner value is not set
|
* @param err The error message to throw when the inner value is not set
|
||||||
* @param primitiveErrMsg The error message to throw when the inner value is a primitive
|
* @param primitiveErr The error message to throw when the inner value is a primitive
|
||||||
* @returns A proxy which will act like the inner value when accessed
|
* @returns A proxy which will act like the inner value when accessed
|
||||||
*/
|
*/
|
||||||
export function proxyInner<T = any>(
|
export function proxyInner<T = any>(err: string | (() => string) = "Proxy inner value is undefined, setInnerValue was never called.", primitiveErr = "proxyInner called on a primitive value. This can happen if you try to destructure a primitive at the same tick as the proxy was created.", isChild = false): [proxy: T, setInnerValue: (innerValue: T) => void] {
|
||||||
errMsg: string | (() => string) = "Proxy inner value is undefined, setInnerValue was never called.",
|
|
||||||
primitiveErrMsg = "proxyInner called on a primitive value. This can happen if you try to destructure a primitive at the same tick as the proxy was created.",
|
|
||||||
isChild = false
|
|
||||||
): [proxy: T, setInnerValue: (innerValue: T) => void] {
|
|
||||||
let isSameTick = true;
|
let isSameTick = true;
|
||||||
if (!isChild) setTimeout(() => isSameTick = false, 0);
|
if (!isChild) setTimeout(() => isSameTick = false, 0);
|
||||||
|
|
||||||
const proxyDummy = Object.assign(function () { }, {
|
const proxyDummy = Object.assign(function () { }, {
|
||||||
[SYM_PROXY_INNER_GET]: function () {
|
[SYM_PROXY_INNER_GET]: function () {
|
||||||
if (proxyDummy[SYM_PROXY_INNER_VALUE] == null) {
|
if (proxyDummy[SYM_PROXY_INNER_VALUE] == null) {
|
||||||
throw new Error(typeof errMsg === "string" ? errMsg : errMsg());
|
throw new Error(typeof err === "string" ? err : err());
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxyDummy[SYM_PROXY_INNER_VALUE];
|
return proxyDummy[SYM_PROXY_INNER_VALUE];
|
||||||
|
@ -85,7 +81,7 @@ export function proxyInner<T = any>(
|
||||||
"\nConsider not destructuring, using findProp or if you really need to destructure, using mapMangledModule instead."
|
"\nConsider not destructuring, using findProp or if you really need to destructure, using mapMangledModule instead."
|
||||||
);
|
);
|
||||||
|
|
||||||
const [recursiveProxy, recursiveSetInnerValue] = proxyInner(errMsg, primitiveErrMsg, true);
|
const [recursiveProxy, recursiveSetInnerValue] = proxyInner(err, primitiveErr, true);
|
||||||
|
|
||||||
recursiveSetInnerValues.push((innerValue: T) => {
|
recursiveSetInnerValues.push((innerValue: T) => {
|
||||||
// Set the inner value of the destructured value as the prop value p of the parent
|
// Set the inner value of the destructured value as the prop value p of the parent
|
||||||
|
@ -100,7 +96,7 @@ export function proxyInner<T = any>(
|
||||||
return Reflect.get(innerTarget, p, innerTarget);
|
return Reflect.get(innerTarget, p, innerTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(primitiveErrMsg);
|
throw new Error(primitiveErr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -171,8 +171,8 @@ function printFilter(filter: FilterFn) {
|
||||||
return String(filter);
|
return String(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapWebpackComponent<P extends AnyRecord>(err: string | (() => string)): [WrapperComponent: LazyComponentType<P>, setInnerComponent: (rawComponent: any, parsedComponent: LazyComponentType<P>) => void] {
|
function wrapWebpackComponent<P extends AnyRecord>(err: string | (() => string)): [WrapperComponent: LazyComponentType<P>, setInnerComponent: (rawComponent: any, parsedComponent: AnyComponentType<P>) => void] {
|
||||||
let InnerComponent = null as LazyComponentType<P> | null;
|
let InnerComponent = null as AnyComponentType<P> | null;
|
||||||
|
|
||||||
let findFailedLogged = false;
|
let findFailedLogged = false;
|
||||||
const WrapperComponent: LazyComponentType<P> = function (props) {
|
const WrapperComponent: LazyComponentType<P> = function (props) {
|
||||||
|
@ -186,7 +186,7 @@ function wrapWebpackComponent<P extends AnyRecord>(err: string | (() => string))
|
||||||
|
|
||||||
WrapperComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent;
|
WrapperComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent;
|
||||||
|
|
||||||
function setInnerComponent(RawComponent: any, ParsedComponent: LazyComponentType<P>) {
|
function setInnerComponent(RawComponent: any, ParsedComponent: AnyComponentType<P>) {
|
||||||
InnerComponent = ParsedComponent;
|
InnerComponent = ParsedComponent;
|
||||||
Object.assign(WrapperComponent, RawComponent);
|
Object.assign(WrapperComponent, RawComponent);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ export function find<T = any>(filter: FilterFn, parse: (module: ModuleExports) =
|
||||||
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
||||||
* @returns The component if found, or a noop component
|
* @returns The component if found, or a noop component
|
||||||
*/
|
*/
|
||||||
export function findComponent<P extends AnyRecord>(filter: FilterFn, parse: (component: ModuleExports) => LazyComponentType<P> = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) {
|
export function findComponent<P extends AnyRecord>(filter: FilterFn, parse: (component: ModuleExports) => AnyComponentType<P> = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) {
|
||||||
if (typeof filter !== "function") {
|
if (typeof filter !== "function") {
|
||||||
throw new Error("Invalid filter. Expected a function got " + typeof filter);
|
throw new Error("Invalid filter. Expected a function got " + typeof filter);
|
||||||
}
|
}
|
||||||
|
@ -311,8 +311,8 @@ export function findComponent<P extends AnyRecord>(filter: FilterFn, parse: (com
|
||||||
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
||||||
* @returns The component if found, or a noop component
|
* @returns The component if found, or a noop component
|
||||||
*/
|
*/
|
||||||
export function findExportedComponent<P extends AnyRecord>(...props: PropsFilter | [...PropsFilter, (component: ModuleExports) => LazyComponentType<P>]) {
|
export function findExportedComponent<P extends AnyRecord>(...props: PropsFilter | [...PropsFilter, (component: ModuleExports) => AnyComponentType<P>]) {
|
||||||
const parse = (typeof props.at(-1) === "function" ? props.pop() : m => m) as (component: ModuleExports) => LazyComponentType<P>;
|
const parse = (typeof props.at(-1) === "function" ? props.pop() : m => m) as (component: ModuleExports) => AnyComponentType<P>;
|
||||||
const newProps = props as PropsFilter;
|
const newProps = props as PropsFilter;
|
||||||
|
|
||||||
const filter = filters.byProps(...newProps);
|
const filter = filters.byProps(...newProps);
|
||||||
|
@ -339,8 +339,8 @@ export function findExportedComponent<P extends AnyRecord>(...props: PropsFilter
|
||||||
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
||||||
* @returns The component if found, or a noop component
|
* @returns The component if found, or a noop component
|
||||||
*/
|
*/
|
||||||
export function findComponentByCode<P extends AnyRecord>(...code: CodeFilter | [...CodeFilter, (component: ModuleExports) => LazyComponentType<P>]) {
|
export function findComponentByCode<P extends AnyRecord>(...code: CodeFilter | [...CodeFilter, (component: ModuleExports) => AnyComponentType<P>]) {
|
||||||
const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => LazyComponentType<P>;
|
const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => AnyComponentType<P>;
|
||||||
const newCode = code as CodeFilter;
|
const newCode = code as CodeFilter;
|
||||||
|
|
||||||
const ComponentResult = findComponent<P>(filters.componentByCode(...newCode), parse, { isIndirect: true });
|
const ComponentResult = findComponent<P>(filters.componentByCode(...newCode), parse, { isIndirect: true });
|
||||||
|
@ -362,8 +362,8 @@ export function findComponentByCode<P extends AnyRecord>(...code: CodeFilter | [
|
||||||
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
|
||||||
* @returns The component if found, or a noop component
|
* @returns The component if found, or a noop component
|
||||||
*/
|
*/
|
||||||
export function findComponentByFields<P extends AnyRecord>(...fields: PropsFilter | [...PropsFilter, (component: ModuleExports) => LazyComponentType<P>]) {
|
export function findComponentByFields<P extends AnyRecord>(...fields: PropsFilter | [...PropsFilter, (component: ModuleExports) => AnyComponentType<P>]) {
|
||||||
const parse = (typeof fields.at(-1) === "function" ? fields.pop() : m => m) as (component: ModuleExports) => LazyComponentType<P>;
|
const parse = (typeof fields.at(-1) === "function" ? fields.pop() : m => m) as (component: ModuleExports) => AnyComponentType<P>;
|
||||||
const newFields = fields as PropsFilter;
|
const newFields = fields as PropsFilter;
|
||||||
|
|
||||||
const ComponentResult = findComponent<P>(filters.componentByFields(...newFields), parse, { isIndirect: true });
|
const ComponentResult = findComponent<P>(filters.componentByFields(...newFields), parse, { isIndirect: true });
|
||||||
|
|
Loading…
Reference in a new issue