summaryrefslogtreecommitdiff
path: root/frontend/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components')
-rw-r--r--frontend/src/components/DeckyRouterState.tsx67
-rw-r--r--frontend/src/components/PluginView.tsx2
-rw-r--r--frontend/src/components/TitleView.tsx20
3 files changed, 79 insertions, 10 deletions
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>
+ );
+};
diff --git a/frontend/src/components/PluginView.tsx b/frontend/src/components/PluginView.tsx
index 65288c05..4bc159e2 100644
--- a/frontend/src/components/PluginView.tsx
+++ b/frontend/src/components/PluginView.tsx
@@ -9,7 +9,7 @@ const PluginView: VFC = () => {
if (activePlugin) {
return (
- <div style={{height: '100%'}}>
+ <div style={{ height: '100%' }}>
<div style={{ position: 'absolute', top: '3px', left: '16px', zIndex: 20 }}>
<DialogButton style={{ minWidth: 0, padding: '10px 12px' }} onClick={closeActivePlugin}>
<FaArrowLeft style={{ display: 'block' }} />
diff --git a/frontend/src/components/TitleView.tsx b/frontend/src/components/TitleView.tsx
index a9e1017a..8ca81028 100644
--- a/frontend/src/components/TitleView.tsx
+++ b/frontend/src/components/TitleView.tsx
@@ -1,23 +1,25 @@
-import { staticClasses, DialogButton } from 'decky-frontend-lib';
+import { DialogButton, staticClasses } from 'decky-frontend-lib';
import { VFC } from 'react';
-import { FaShoppingBag } from "react-icons/fa";
+import { FaShoppingBag } from 'react-icons/fa';
import { useDeckyState } from './DeckyState';
const TitleView: VFC = () => {
const { activePlugin } = useDeckyState();
- const openPluginStore = () => fetch("http://127.0.0.1:1337/methods/open_plugin_store", {method: "POST"});
+ const openPluginStore = () => fetch('http://127.0.0.1:1337/methods/open_plugin_store', { method: 'POST' });
if (activePlugin === null) {
- return <div className={staticClasses.Title}>
- Decky
- <div style={{ position: 'absolute', top: '3px', right: '16px', zIndex: 20 }}>
- <DialogButton style={{ minWidth: 0, padding: '10px 12px' }} onClick={openPluginStore}>
+ return (
+ <div className={staticClasses.Title}>
+ Decky
+ <div style={{ position: 'absolute', top: '3px', right: '16px', zIndex: 20 }}>
+ <DialogButton style={{ minWidth: 0, padding: '10px 12px' }} onClick={openPluginStore}>
<FaShoppingBag style={{ display: 'block' }} />
- </DialogButton>
+ </DialogButton>
</div>
- </div>;
+ </div>
+ );
}
return (