From 007860f8f771a7ee62b1c384fbe4f741528a75d5 Mon Sep 17 00:00:00 2001
From: AAGaming <aagaming00@protonmail.com>
Date: Mon, 30 May 2022 14:26:54 -0400
Subject: react: Add Router hook & fix typescript issues (#68)

* add rollup watch command, add pnpm lockfile

* wait for react

* add WIP patcher, window hook, and webpack

* fix typescript, fix React, lint, add pnpm to gitignore

* actually fix react

* show frontend JS errors in console

* cleanup

* Add Router hook

* Remove console.log

* Expose routerHook in createPluginAPI

Co-authored-by: Jonas Dellinger <jonas@dellinger.dev>
---
 frontend/src/components/DeckyRouterState.tsx | 67 ++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 frontend/src/components/DeckyRouterState.tsx

(limited to 'frontend/src/components/DeckyRouterState.tsx')

diff --git a/frontend/src/components/DeckyRouterState.tsx b/frontend/src/components/DeckyRouterState.tsx
new file mode 100644
index 00000000..3c9a5f9b
--- /dev/null
+++ b/frontend/src/components/DeckyRouterState.tsx
@@ -0,0 +1,67 @@
+import { ComponentType, FC, createContext, useContext, useEffect, useState } from 'react';
+
+interface PublicDeckyRouterState {
+  routes: Map<string, ComponentType>;
+}
+
+export class DeckyRouterState {
+  private _routes: Map<string, ComponentType> = new Map<string, ComponentType>();
+
+  public eventBus = new EventTarget();
+
+  publicState(): PublicDeckyRouterState {
+    return { routes: this._routes };
+  }
+
+  addRoute(path: string, render: ComponentType) {
+    this._routes.set(path, render);
+    this.notifyUpdate();
+  }
+
+  removeRoute(path: string) {
+    this._routes.delete(path);
+    this.notifyUpdate();
+  }
+
+  private notifyUpdate() {
+    this.eventBus.dispatchEvent(new Event('update'));
+  }
+}
+
+interface DeckyRouterStateContext extends PublicDeckyRouterState {
+  addRoute(path: string, render: ComponentType): void;
+  removeRoute(path: string): void;
+}
+
+const DeckyRouterStateContext = createContext<DeckyRouterStateContext>(null as any);
+
+export const useDeckyRouterState = () => useContext(DeckyRouterStateContext);
+
+interface Props {
+  deckyRouterState: DeckyRouterState;
+}
+
+export const DeckyRouterStateContextProvider: FC<Props> = ({ children, deckyRouterState }) => {
+  const [publicDeckyRouterState, setPublicDeckyRouterState] = useState<PublicDeckyRouterState>({
+    ...deckyRouterState.publicState(),
+  });
+
+  useEffect(() => {
+    function onUpdate() {
+      setPublicDeckyRouterState({ ...deckyRouterState.publicState() });
+    }
+
+    deckyRouterState.eventBus.addEventListener('update', onUpdate);
+
+    return () => deckyRouterState.eventBus.removeEventListener('update', onUpdate);
+  }, []);
+
+  const addRoute = (path: string, render: ComponentType) => deckyRouterState.addRoute(path, render);
+  const removeRoute = (path: string) => deckyRouterState.removeRoute(path);
+
+  return (
+    <DeckyRouterStateContext.Provider value={{ ...publicDeckyRouterState, addRoute, removeRoute }}>
+      {children}
+    </DeckyRouterStateContext.Provider>
+  );
+};
-- 
cgit v1.2.3

