diff options
| author | AAGaming <aagaming00@protonmail.com> | 2022-05-30 14:26:54 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-30 20:26:54 +0200 |
| commit | 007860f8f771a7ee62b1c384fbe4f741528a75d5 (patch) | |
| tree | e901ec893500f0531ebb66b5066b2003086570b3 /frontend/src/components | |
| parent | 44776b393e984e5968c8b092fade56644c39a4a7 (diff) | |
| download | decky-loader-007860f8f771a7ee62b1c384fbe4f741528a75d5.tar.gz decky-loader-007860f8f771a7ee62b1c384fbe4f741528a75d5.zip | |
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>
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/DeckyRouterState.tsx | 67 | ||||
| -rw-r--r-- | frontend/src/components/PluginView.tsx | 2 | ||||
| -rw-r--r-- | frontend/src/components/TitleView.tsx | 20 |
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 ( |
