diff options
| author | AAGaming <aa@mail.catvibers.me> | 2022-10-24 19:14:56 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-24 16:14:56 -0700 |
| commit | 84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10 (patch) | |
| tree | 20b13066c6256cc6ca1beac085094c7964226a37 /frontend/src/router-hook.tsx | |
| parent | 2e6b3834da357c7e81821ce60bad36f54dd9fa6e (diff) | |
| download | decky-loader-84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10.tar.gz decky-loader-84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10.zip | |
preview 10/21/2022 fixes (#234)
* initial fixes: everything working except toasts and patch notes
* tabshook changes, disable toaster for now
* prettier
* oops
* implement custom toaster because I am tired of Valve's shit
also fix QAM not injecting sometimes
* remove extra logging
* add findSP, fix patch notes, fix vscode screwup
* fix patch notes
* show error when plugin frontends fail to load
* add get_tab_lambda
* add css and has_element helpers to Tab
* small modals fixup
* Don't forceUpdate QuickAccess on stable
* add routes prop used to get tabs component
* add more dev utils to DFL global
Diffstat (limited to 'frontend/src/router-hook.tsx')
| -rw-r--r-- | frontend/src/router-hook.tsx | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/frontend/src/router-hook.tsx b/frontend/src/router-hook.tsx index 8414db2c..bf3ae0cb 100644 --- a/frontend/src/router-hook.tsx +++ b/frontend/src/router-hook.tsx @@ -1,8 +1,13 @@ import { Patch, afterPatch, findModuleChild } from 'decky-frontend-lib'; -import { ReactElement, ReactNode, cloneElement, createElement, memo } from 'react'; +import { FC, ReactElement, ReactNode, cloneElement, createElement, memo } from 'react'; import type { Route } from 'react-router'; import { + DeckyGlobalComponentsState, + DeckyGlobalComponentsStateContextProvider, + useDeckyGlobalComponentsState, +} from './components/DeckyGlobalComponentsState'; +import { DeckyRouterState, DeckyRouterStateContextProvider, RoutePatch, @@ -22,8 +27,10 @@ class RouterHook extends Logger { private memoizedRouter: any; private gamepadWrapper: any; private routerState: DeckyRouterState = new DeckyRouterState(); + private globalComponentsState: DeckyGlobalComponentsState = new DeckyGlobalComponentsState(); private wrapperPatch: Patch; private routerPatch?: Patch; + public routes?: any[]; constructor() { super('RouterHook'); @@ -42,24 +49,28 @@ class RouterHook extends Logger { let Route: new () => Route; // Used to store the new replicated routes we create to allow routes to be unpatched. - let toReplace = new Map<string, ReactNode>(); - const DeckyWrapper = ({ children }: { children: ReactElement }) => { - const { routes, routePatches } = useDeckyRouterState(); - - const routeList = children.props.children[0].props.children; - + const processList = ( + routeList: any[], + routes: Map<string, RouterEntry> | null, + routePatches: Map<string, Set<RoutePatch>>, + save: boolean, + ) => { + this.debug('Route list: ', routeList); + if (save) this.routes = routeList; let routerIndex = routeList.length; - if (!routeList[routerIndex - 1]?.length || routeList[routerIndex - 1]?.length !== routes.size) { - if (routeList[routerIndex - 1]?.length && routeList[routerIndex - 1].length !== routes.size) routerIndex--; - const newRouterArray: ReactElement[] = []; - routes.forEach(({ component, props }, path) => { - newRouterArray.push( - <Route path={path} {...props}> - {createElement(component)} - </Route>, - ); - }); - routeList[routerIndex] = newRouterArray; + if (routes) { + if (!routeList[routerIndex - 1]?.length || routeList[routerIndex - 1]?.length !== routes.size) { + if (routeList[routerIndex - 1]?.length && routeList[routerIndex - 1].length !== routes.size) routerIndex--; + const newRouterArray: ReactElement[] = []; + routes.forEach(({ component, props }, path) => { + newRouterArray.push( + <Route path={path} {...props}> + {createElement(component)} + </Route>, + ); + }); + routeList[routerIndex] = newRouterArray; + } } routeList.forEach((route: Route, index: number) => { const replaced = toReplace.get(route?.props?.path as string); @@ -85,19 +96,40 @@ class RouterHook extends Logger { }); } }); + }; + let toReplace = new Map<string, ReactNode>(); + const DeckyWrapper = ({ children }: { children: ReactElement }) => { + const { routes, routePatches } = useDeckyRouterState(); + const mainRouteList = children.props.children[0].props.children; + const ingameRouteList = children.props.children[1].props.children; // /appoverlay and /apprunning + processList(mainRouteList, routes, routePatches, true); + processList(ingameRouteList, null, routePatches, false); + this.debug('Rerendered routes list'); return children; }; + let renderedComponents: ReactElement[] = []; + + const DeckyGlobalComponentsWrapper = () => { + const { components } = useDeckyGlobalComponentsState(); + if (renderedComponents.length != components.size) { + this.debug('Rerendering global components'); + renderedComponents = Array.from(components.values()).map((GComponent) => <GComponent />); + } + return <>{renderedComponents}</>; + }; + this.wrapperPatch = afterPatch(this.gamepadWrapper, 'render', (_: any, ret: any) => { - if (ret?.props?.children?.props?.children?.length == 5) { + if (ret?.props?.children?.props?.children?.length == 5 || ret?.props?.children?.props?.children?.length == 4) { + const idx = ret?.props?.children?.props?.children?.length == 4 ? 1 : 2; if ( - ret.props.children.props.children[2]?.props?.children?.[0]?.type?.type + ret.props.children.props.children[idx]?.props?.children?.[0]?.type?.type ?.toString() ?.includes('GamepadUI.Settings.Root()') ) { if (!this.router) { - this.router = ret.props.children.props.children[2]?.props?.children?.[0]?.type; + this.router = ret.props.children.props.children[idx]?.props?.children?.[0]?.type; this.routerPatch = afterPatch(this.router, 'type', (_: any, ret: any) => { if (!Route) Route = ret.props.children[0].props.children.find((x: any) => x.props.path == '/createaccount').type; @@ -111,7 +143,12 @@ class RouterHook extends Logger { this.memoizedRouter = memo(this.router.type); this.memoizedRouter.isDeckyRouter = true; } - ret.props.children.props.children[2].props.children[0].type = this.memoizedRouter; + ret.props.children.props.children.push( + <DeckyGlobalComponentsStateContextProvider deckyGlobalComponentsState={this.globalComponentsState}> + <DeckyGlobalComponentsWrapper /> + </DeckyGlobalComponentsStateContextProvider>, + ); + ret.props.children.props.children[idx].props.children[0].type = this.memoizedRouter; } } return ret; @@ -126,6 +163,14 @@ class RouterHook extends Logger { return this.routerState.addPatch(path, patch); } + addGlobalComponent(name: string, component: FC) { + this.globalComponentsState.addComponent(name, component); + } + + removeGlobalComponent(name: string) { + this.globalComponentsState.removeComponent(name); + } + removePatch(path: string, patch: RoutePatch) { this.routerState.removePatch(path, patch); } |
