2023-11-23 05:43:22 +00:00
|
|
|
/*
|
|
|
|
* Vencord, a Discord client mod
|
|
|
|
* Copyright (c) 2023 Vendicated and contributors
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { makeLazy } from "./lazy";
|
|
|
|
|
2024-06-12 20:45:54 +00:00
|
|
|
export type LazyComponentType<T extends object = any> = React.ComponentType<T> & Record<PropertyKey, any>;
|
2024-06-12 20:06:20 +00:00
|
|
|
|
|
|
|
export const SYM_LAZY_COMPONENT_INNER = Symbol.for("vencord.lazyComponent.inner");
|
|
|
|
|
2023-11-23 05:43:22 +00:00
|
|
|
/**
|
|
|
|
* A lazy component. The factory method is called on first render.
|
2024-05-08 09:44:18 +00:00
|
|
|
*
|
2024-05-03 02:18:12 +00:00
|
|
|
* @param factory Function returning a component
|
2023-11-23 05:43:22 +00:00
|
|
|
* @param attempts How many times to try to get the component before giving up
|
|
|
|
* @returns Result of factory function
|
|
|
|
*/
|
2024-06-12 20:45:54 +00:00
|
|
|
export function LazyComponent<T extends object = any>(factory: () => LazyComponentType<T>, attempts = 5) {
|
2024-05-07 04:13:46 +00:00
|
|
|
const get = makeLazy(factory, attempts, { isIndirect: true });
|
2024-05-03 02:18:12 +00:00
|
|
|
|
2024-06-12 20:06:20 +00:00
|
|
|
let InnerComponent = null as LazyComponentType<T> | null;
|
2024-05-05 02:56:02 +00:00
|
|
|
|
2024-05-07 04:13:46 +00:00
|
|
|
let lazyFailedLogged = false;
|
|
|
|
const LazyComponent = (props: T) => {
|
2024-05-05 02:56:02 +00:00
|
|
|
if (!get.$$vencordLazyFailed()) {
|
2024-05-07 04:13:46 +00:00
|
|
|
const ResultComponent = get();
|
|
|
|
if (ResultComponent != null) {
|
|
|
|
InnerComponent = ResultComponent;
|
2024-05-30 02:42:14 +00:00
|
|
|
Object.assign(LazyComponent, ResultComponent);
|
2024-05-07 04:13:46 +00:00
|
|
|
}
|
2024-05-05 02:56:02 +00:00
|
|
|
}
|
2024-05-03 02:18:12 +00:00
|
|
|
|
2024-05-07 04:13:46 +00:00
|
|
|
if (InnerComponent === null && !lazyFailedLogged) {
|
|
|
|
if (get.$$vencordLazyFailed()) {
|
|
|
|
lazyFailedLogged = true;
|
|
|
|
}
|
2023-11-25 00:32:21 +00:00
|
|
|
|
2024-05-07 04:13:46 +00:00
|
|
|
console.error(`LazyComponent factory failed:\n\n${factory}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return InnerComponent && <InnerComponent {...props} />;
|
|
|
|
};
|
2023-11-25 00:32:21 +00:00
|
|
|
|
2024-06-12 20:06:20 +00:00
|
|
|
LazyComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent;
|
|
|
|
|
|
|
|
return LazyComponent as LazyComponentType<T>;
|
2023-11-23 05:43:22 +00:00
|
|
|
}
|