ModularVencord/src/utils/lazyReact.tsx
2024-05-08 06:44:18 -03:00

51 lines
1.6 KiB
TypeScript

/*
* Vencord, a Discord client mod
* Copyright (c) 2023 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { makeLazy } from "./lazy";
/**
* A lazy component. The factory method is called on first render.
*
* IMPORTANT: You cannot access properties set on the lazy component using this method.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = LazyComponent(...);
* console.log(Component.Types); // This will not work
* ````
* @param factory Function returning a component
* @param attempts How many times to try to get the component before giving up
* @returns Result of factory function
*/
export function LazyComponent<T extends object = any>(factory: () => React.ComponentType<T>, attempts = 5) {
const get = makeLazy(factory, attempts, { isIndirect: true });
let InnerComponent = null as React.ComponentType<T> | null;
let lazyFailedLogged = false;
const LazyComponent = (props: T) => {
// @ts-ignore
if (!get.$$vencordLazyFailed()) {
const ResultComponent = get();
if (ResultComponent != null) {
InnerComponent = ResultComponent;
}
}
if (InnerComponent === null && !lazyFailedLogged) {
// @ts-ignore
if (get.$$vencordLazyFailed()) {
lazyFailedLogged = true;
}
console.error(`LazyComponent factory failed:\n\n${factory}`);
}
return InnerComponent && <InnerComponent {...props} />;
};
return LazyComponent as React.ComponentType<T>;
}