aboutsummaryrefslogtreecommitdiff
path: root/src/utils/misc.tsx
diff options
context:
space:
mode:
authorVendicated <vendicated@riseup.net>2022-08-31 04:07:16 +0200
committerVendicated <vendicated@riseup.net>2022-08-31 04:07:16 +0200
commit98cb301df53305f397ac6e1b4e603c930820f228 (patch)
tree8c3bc642d0871a38f99aa2c2e8586bd7310cb361 /src/utils/misc.tsx
parentcb288e204dd531b31f957f82150398d22930fdeb (diff)
downloadVencord-98cb301df53305f397ac6e1b4e603c930820f228.tar.gz
Vencord-98cb301df53305f397ac6e1b4e603c930820f228.tar.bz2
Vencord-98cb301df53305f397ac6e1b4e603c930820f228.zip
Make Settings & Settings Page
Diffstat (limited to 'src/utils/misc.tsx')
-rw-r--r--src/utils/misc.tsx61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx
new file mode 100644
index 0000000..ded052b
--- /dev/null
+++ b/src/utils/misc.tsx
@@ -0,0 +1,61 @@
+import { React } from "../webpack";
+
+/**
+ * Makes a lazy function. On first call, the value is computed.
+ * On subsequent calls, the same computed value will be returned
+ * @param factory Factory function
+ */
+export function lazy<T>(factory: () => T): () => T {
+ let cache: T;
+ return () => {
+ return cache ?? (cache = factory());
+ };
+}
+
+/**
+ * Await a promise
+ * @param factory Factory
+ * @param fallbackValue The fallback value that will be used until the promise resolved
+ * @returns A state that will either be null or the result of the promise
+ */
+export function useAwaiter<T>(factory: () => Promise<T>, fallbackValue: T | null = null): T | null {
+ const [res, setRes] = React.useState<T | null>(fallbackValue);
+
+ React.useEffect(() => {
+ factory().then(setRes);
+ }, []);
+
+ return res;
+}
+
+/**
+ * A lazy component. The factory method is called on first render. For example useful
+ * for const Component = LazyComponent(() => findByDisplayName("...").default)
+ * @param factory Function returning a Component
+ * @returns Result of factory function
+ */
+export function LazyComponent<T = any>(factory: () => React.ComponentType<T>) {
+ return (props: T) => {
+ const Component = React.useMemo(factory, []);
+ return <Component {...props} />;
+ };
+}
+
+/**
+ * Recursively merges defaults into an object and returns the same object
+ * @param obj Object
+ * @param defaults Defaults
+ * @returns obj
+ */
+export function mergeDefaults<T>(obj: T, defaults: T): T {
+ for (const key in defaults) {
+ const v = defaults[key];
+ if (typeof v === "object" && !Array.isArray(v)) {
+ obj[key] ??= {} as any;
+ mergeDefaults(obj[key], v);
+ } else {
+ obj[key] ??= v;
+ }
+ }
+ return obj;
+} \ No newline at end of file